MBS-12224: Keep tag counts updated via triggers

Three new trigger functions are added:

 * update_tag_counts_for_raw_insert
 * update_tag_counts_for_raw_update
 * update_tag_counts_for_raw_delete

These are executed for insertions/updates/deletions on the raw tag
tables, and update both the aggregate vote counts (area_tag.count, etc.)
and tag.ref_count.

Since these functions are written to work for any entity type, the
tagged entity type must be passed in as an argument to the function
where the trigger is invoked; a new ENUM, taggable_entity_type, has been
added to check that the argument is trusted.

The upgrade script also resolves MBS-5359 by rebuilding all the counts.

Existing Perl code that managed these counts has been removed from
Data::EntityTag.

For tests, see t/pgtap/tag_counts.sql.
This commit is contained in:
Michael Wiencek
2021-12-13 13:08:41 -06:00
committed by yvanzo
parent f847f540f9
commit 2c3c24770c
21 changed files with 1445 additions and 389 deletions

@ -1565,6 +1565,101 @@ CREATE OR REPLACE FUNCTION controlled_for_whitespace(TEXT) RETURNS boolean AS $$
SELECT NOT padded_by_whitespace($1);
$$ LANGUAGE SQL IMMUTABLE SET search_path = musicbrainz, public;
CREATE OR REPLACE FUNCTION update_aggregate_tag_count(entity_type taggable_entity_type, entity_id INTEGER, tag_id INTEGER, count_change SMALLINT)
RETURNS VOID AS $$
BEGIN
-- Insert-or-update the aggregate vote count for the given (entity_id, tag_id).
EXECUTE format(
$SQL$
INSERT INTO %1$I AS agg (%2$I, tag, count)
VALUES ($1, $2, $3)
ON CONFLICT (%2$I, tag) DO UPDATE SET count = agg.count + $3
$SQL$,
entity_type::TEXT || '_tag',
entity_type::TEXT
) USING entity_id, tag_id, count_change;
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION delete_unused_aggregate_tag(entity_type taggable_entity_type, entity_id INTEGER, tag_id INTEGER)
RETURNS VOID AS $$
BEGIN
-- Delete the aggregate tag row for (entity_id, tag_id) if no raw tag pair
-- exists for the same.
--
-- Note that an aggregate vote count of 0 doesn't imply there are no raw
-- tags; it's a sum of all the votes, so it can also mean that there's a
-- downvote for every upvote.
EXECUTE format(
$SQL$
DELETE FROM %1$I
WHERE %2$I = $1
AND tag = $2
AND NOT EXISTS (SELECT 1 FROM %3$I WHERE %2$I = $1 AND tag = $2)
$SQL$,
entity_type::TEXT || '_tag',
entity_type::TEXT,
entity_type::TEXT || '_tag_raw'
) USING entity_id, tag_id;
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION update_tag_counts_for_raw_insert()
RETURNS trigger AS $$
DECLARE
entity_type taggable_entity_type;
new_entity_id INTEGER;
BEGIN
entity_type := TG_ARGV[0]::taggable_entity_type;
EXECUTE format('SELECT ($1).%s', entity_type::TEXT) INTO new_entity_id USING NEW;
PERFORM update_aggregate_tag_count(entity_type, new_entity_id, NEW.tag, (CASE WHEN NEW.is_upvote THEN 1 ELSE -1 END)::SMALLINT);
UPDATE tag SET ref_count = ref_count + 1 WHERE id = NEW.tag;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION update_tag_counts_for_raw_update()
RETURNS trigger AS $$
DECLARE
entity_type taggable_entity_type;
new_entity_id INTEGER;
old_entity_id INTEGER;
BEGIN
entity_type := TG_ARGV[0]::taggable_entity_type;
EXECUTE format('SELECT ($1).%s', entity_type) INTO new_entity_id USING NEW;
EXECUTE format('SELECT ($1).%s', entity_type) INTO old_entity_id USING OLD;
IF (old_entity_id = new_entity_id AND OLD.tag = NEW.tag AND OLD.is_upvote != NEW.is_upvote) THEN
-- Case 1: only the vote changed.
PERFORM update_aggregate_tag_count(entity_type, old_entity_id, OLD.tag, (CASE WHEN OLD.is_upvote THEN -2 ELSE 2 END)::SMALLINT);
ELSIF (old_entity_id != new_entity_id OR OLD.tag != NEW.tag OR OLD.is_upvote != NEW.is_upvote) THEN
-- Case 2: the entity, tag, or vote changed.
PERFORM update_aggregate_tag_count(entity_type, old_entity_id, OLD.tag, (CASE WHEN OLD.is_upvote THEN -1 ELSE 1 END)::SMALLINT);
PERFORM update_aggregate_tag_count(entity_type, new_entity_id, NEW.tag, (CASE WHEN NEW.is_upvote THEN 1 ELSE -1 END)::SMALLINT);
PERFORM delete_unused_aggregate_tag(entity_type, old_entity_id, OLD.tag);
END IF;
IF OLD.tag != NEW.tag THEN
UPDATE tag SET ref_count = ref_count - 1 WHERE id = OLD.tag;
UPDATE tag SET ref_count = ref_count + 1 WHERE id = NEW.tag;
END IF;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION update_tag_counts_for_raw_delete()
RETURNS trigger AS $$
DECLARE
entity_type taggable_entity_type;
old_entity_id INTEGER;
BEGIN
entity_type := TG_ARGV[0]::taggable_entity_type;
EXECUTE format('SELECT ($1).%s', entity_type::TEXT) INTO old_entity_id USING OLD;
PERFORM update_aggregate_tag_count(entity_type, old_entity_id, OLD.tag, (CASE WHEN OLD.is_upvote THEN -1 ELSE 1 END)::SMALLINT);
PERFORM delete_unused_aggregate_tag(entity_type, old_entity_id, OLD.tag);
UPDATE tag SET ref_count = ref_count - 1 WHERE id = OLD.tag;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION delete_unused_tag(tag_id INT)
RETURNS void AS $$
BEGIN

@ -1271,6 +1271,105 @@ CREATE TRIGGER update_aggregate_rating_for_update AFTER UPDATE ON work_rating_ra
CREATE TRIGGER update_aggregate_rating_for_delete AFTER DELETE ON work_rating_raw
FOR EACH ROW EXECUTE PROCEDURE update_aggregate_rating_for_raw_delete('work');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON area_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('area');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON area_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('area');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON area_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('area');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON artist_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('artist');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON artist_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('artist');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON artist_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('artist');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON event_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('event');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON event_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('event');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON event_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('event');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON instrument_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('instrument');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON instrument_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('instrument');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON instrument_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('instrument');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON label_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('label');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON label_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('label');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON label_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('label');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON place_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('place');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON place_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('place');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON place_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('place');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON recording_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('recording');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON recording_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('recording');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON recording_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('recording');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON release_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('release');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON release_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('release');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON release_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('release');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON release_group_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('release_group');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON release_group_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('release_group');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON release_group_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('release_group');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON series_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('series');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON series_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('series');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON series_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('series');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON work_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('work');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON work_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('work');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON work_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('work');
COMMIT;
-- vi: set ts=4 sw=4 et :

@ -24,4 +24,18 @@ CREATE TYPE ratable_entity_type AS ENUM (
'work'
);
CREATE TYPE taggable_entity_type AS ENUM (
'area',
'artist',
'event',
'instrument',
'label',
'place',
'recording',
'release',
'release_group',
'series',
'work'
);
COMMIT;

@ -64,6 +64,7 @@ DROP FUNCTION del_collection_sub_on_delete();
DROP FUNCTION del_collection_sub_on_private();
DROP FUNCTION delete_orphaned_recordings();
DROP FUNCTION delete_ratings(enttype TEXT, ids INTEGER[]);
DROP FUNCTION delete_unused_aggregate_tag(entity_type taggable_entity_type, entity_id INTEGER, tag_id INTEGER);
DROP FUNCTION delete_unused_tag(tag_id INT);
DROP FUNCTION delete_unused_url(ids INTEGER[]);
DROP FUNCTION deny_deprecated_links();
@ -110,3 +111,7 @@ DROP FUNCTION simplify_search_hints();
DROP FUNCTION track_count_matches_cdtoc(medium, int);
DROP FUNCTION trg_delete_unused_tag();
DROP FUNCTION trg_delete_unused_tag_ref();
DROP FUNCTION update_aggregate_tag_count(entity_type taggable_entity_type, entity_id INTEGER, tag_id INTEGER, count_change SMALLINT);
DROP FUNCTION update_tag_counts_for_raw_delete();
DROP FUNCTION update_tag_counts_for_raw_insert();
DROP FUNCTION update_tag_counts_for_raw_update();

@ -359,3 +359,36 @@ DROP TRIGGER apply_artist_release_group_pending_updates ON release_group_seconda
DROP TRIGGER apply_artist_release_pending_updates ON release_label;
DROP TRIGGER apply_artist_release_group_pending_updates ON track;
DROP TRIGGER apply_artist_release_pending_updates ON track;
DROP TRIGGER update_counts_for_insert ON area_tag_raw;
DROP TRIGGER update_counts_for_update ON area_tag_raw;
DROP TRIGGER update_counts_for_delete ON area_tag_raw;
DROP TRIGGER update_counts_for_insert ON artist_tag_raw;
DROP TRIGGER update_counts_for_update ON artist_tag_raw;
DROP TRIGGER update_counts_for_delete ON artist_tag_raw;
DROP TRIGGER update_counts_for_insert ON event_tag_raw;
DROP TRIGGER update_counts_for_update ON event_tag_raw;
DROP TRIGGER update_counts_for_delete ON event_tag_raw;
DROP TRIGGER update_counts_for_insert ON instrument_tag_raw;
DROP TRIGGER update_counts_for_update ON instrument_tag_raw;
DROP TRIGGER update_counts_for_delete ON instrument_tag_raw;
DROP TRIGGER update_counts_for_insert ON label_tag_raw;
DROP TRIGGER update_counts_for_update ON label_tag_raw;
DROP TRIGGER update_counts_for_delete ON label_tag_raw;
DROP TRIGGER update_counts_for_insert ON place_tag_raw;
DROP TRIGGER update_counts_for_update ON place_tag_raw;
DROP TRIGGER update_counts_for_delete ON place_tag_raw;
DROP TRIGGER update_counts_for_insert ON recording_tag_raw;
DROP TRIGGER update_counts_for_update ON recording_tag_raw;
DROP TRIGGER update_counts_for_delete ON recording_tag_raw;
DROP TRIGGER update_counts_for_insert ON release_tag_raw;
DROP TRIGGER update_counts_for_update ON release_tag_raw;
DROP TRIGGER update_counts_for_delete ON release_tag_raw;
DROP TRIGGER update_counts_for_insert ON release_group_tag_raw;
DROP TRIGGER update_counts_for_update ON release_group_tag_raw;
DROP TRIGGER update_counts_for_delete ON release_group_tag_raw;
DROP TRIGGER update_counts_for_insert ON series_tag_raw;
DROP TRIGGER update_counts_for_update ON series_tag_raw;
DROP TRIGGER update_counts_for_delete ON series_tag_raw;
DROP TRIGGER update_counts_for_insert ON work_tag_raw;
DROP TRIGGER update_counts_for_update ON work_tag_raw;
DROP TRIGGER update_counts_for_delete ON work_tag_raw;

@ -5,3 +5,4 @@ DROP TYPE IF EXISTS cover_art_presence;
DROP TYPE IF EXISTS event_art_presence;
DROP TYPE IF EXISTS fluency;
DROP TYPE IF EXISTS oauth_code_challenge_method;
DROP TYPE IF EXISTS taggable_entity_type;

@ -0,0 +1,273 @@
\set ON_ERROR_STOP 1
BEGIN;
DELETE FROM area_tag a WHERE NOT EXISTS (
SELECT 1
FROM area_tag_raw r
WHERE r.area = a.area AND r.tag = a.tag
);
UPDATE area_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM area_tag_raw r
WHERE r.area = a.area AND r.tag = a.tag
GROUP BY r.area, r.tag
);
DELETE FROM artist_tag a WHERE NOT EXISTS (
SELECT 1
FROM artist_tag_raw r
WHERE r.artist = a.artist AND r.tag = a.tag
);
UPDATE artist_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM artist_tag_raw r
WHERE r.artist = a.artist AND r.tag = a.tag
GROUP BY r.artist, r.tag
);
DELETE FROM event_tag a WHERE NOT EXISTS (
SELECT 1
FROM event_tag_raw r
WHERE r.event = a.event AND r.tag = a.tag
);
UPDATE event_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM event_tag_raw r
WHERE r.event = a.event AND r.tag = a.tag
GROUP BY r.event, r.tag
);
DELETE FROM instrument_tag a WHERE NOT EXISTS (
SELECT 1
FROM instrument_tag_raw r
WHERE r.instrument = a.instrument AND r.tag = a.tag
);
UPDATE instrument_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM instrument_tag_raw r
WHERE r.instrument = a.instrument AND r.tag = a.tag
GROUP BY r.instrument, r.tag
);
DELETE FROM label_tag a WHERE NOT EXISTS (
SELECT 1
FROM label_tag_raw r
WHERE r.label = a.label AND r.tag = a.tag
);
UPDATE label_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM label_tag_raw r
WHERE r.label = a.label AND r.tag = a.tag
GROUP BY r.label, r.tag
);
DELETE FROM place_tag a WHERE NOT EXISTS (
SELECT 1
FROM place_tag_raw r
WHERE r.place = a.place AND r.tag = a.tag
);
UPDATE place_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM place_tag_raw r
WHERE r.place = a.place AND r.tag = a.tag
GROUP BY r.place, r.tag
);
DELETE FROM recording_tag a WHERE NOT EXISTS (
SELECT 1
FROM recording_tag_raw r
WHERE r.recording = a.recording AND r.tag = a.tag
);
UPDATE recording_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM recording_tag_raw r
WHERE r.recording = a.recording AND r.tag = a.tag
GROUP BY r.recording, r.tag
);
DELETE FROM release_tag a WHERE NOT EXISTS (
SELECT 1
FROM release_tag_raw r
WHERE r.release = a.release AND r.tag = a.tag
);
UPDATE release_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM release_tag_raw r
WHERE r.release = a.release AND r.tag = a.tag
GROUP BY r.release, r.tag
);
DELETE FROM release_group_tag a WHERE NOT EXISTS (
SELECT 1
FROM release_group_tag_raw r
WHERE r.release_group = a.release_group AND r.tag = a.tag
);
UPDATE release_group_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM release_group_tag_raw r
WHERE r.release_group = a.release_group AND r.tag = a.tag
GROUP BY r.release_group, r.tag
);
DELETE FROM series_tag a WHERE NOT EXISTS (
SELECT 1
FROM series_tag_raw r
WHERE r.series = a.series AND r.tag = a.tag
);
UPDATE series_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM series_tag_raw r
WHERE r.series = a.series AND r.tag = a.tag
GROUP BY r.series, r.tag
);
DELETE FROM work_tag a WHERE NOT EXISTS (
SELECT 1
FROM work_tag_raw r
WHERE r.work = a.work AND r.tag = a.tag
);
UPDATE work_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM work_tag_raw r
WHERE r.work = a.work AND r.tag = a.tag
GROUP BY r.work, r.tag
);
UPDATE tag t SET ref_count = (
(SELECT count(*) FROM area_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM artist_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM event_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM instrument_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM label_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM place_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM recording_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM release_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM release_group_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM series_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM work_tag_raw r WHERE r.tag = t.id)
);
DELETE FROM tag WHERE ref_count = 0;
CREATE TYPE taggable_entity_type AS ENUM (
'area',
'artist',
'event',
'instrument',
'label',
'place',
'recording',
'release',
'release_group',
'series',
'work'
);
CREATE OR REPLACE FUNCTION update_aggregate_tag_count(entity_type taggable_entity_type, entity_id INTEGER, tag_id INTEGER, count_change SMALLINT)
RETURNS VOID AS $$
BEGIN
-- Insert-or-update the aggregate vote count for the given (entity_id, tag_id).
EXECUTE format(
$SQL$
INSERT INTO %1$I AS agg (%2$I, tag, count)
VALUES ($1, $2, $3)
ON CONFLICT (%2$I, tag) DO UPDATE SET count = agg.count + $3
$SQL$,
entity_type::TEXT || '_tag',
entity_type::TEXT
) USING entity_id, tag_id, count_change;
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION delete_unused_aggregate_tag(entity_type taggable_entity_type, entity_id INTEGER, tag_id INTEGER)
RETURNS VOID AS $$
BEGIN
-- Delete the aggregate tag row for (entity_id, tag_id) if no raw tag pair
-- exists for the same.
--
-- Note that an aggregate vote count of 0 doesn't imply there are no raw
-- tags; it's a sum of all the votes, so it can also mean that there's a
-- downvote for every upvote.
EXECUTE format(
$SQL$
DELETE FROM %1$I
WHERE %2$I = $1
AND tag = $2
AND NOT EXISTS (SELECT 1 FROM %3$I WHERE %2$I = $1 AND tag = $2)
$SQL$,
entity_type::TEXT || '_tag',
entity_type::TEXT,
entity_type::TEXT || '_tag_raw'
) USING entity_id, tag_id;
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION update_tag_counts_for_raw_insert()
RETURNS trigger AS $$
DECLARE
entity_type taggable_entity_type;
new_entity_id INTEGER;
BEGIN
entity_type := TG_ARGV[0]::taggable_entity_type;
EXECUTE format('SELECT ($1).%s', entity_type::TEXT) INTO new_entity_id USING NEW;
PERFORM update_aggregate_tag_count(entity_type, new_entity_id, NEW.tag, (CASE WHEN NEW.is_upvote THEN 1 ELSE -1 END)::SMALLINT);
UPDATE tag SET ref_count = ref_count + 1 WHERE id = NEW.tag;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION update_tag_counts_for_raw_update()
RETURNS trigger AS $$
DECLARE
entity_type taggable_entity_type;
new_entity_id INTEGER;
old_entity_id INTEGER;
BEGIN
entity_type := TG_ARGV[0]::taggable_entity_type;
EXECUTE format('SELECT ($1).%s', entity_type) INTO new_entity_id USING NEW;
EXECUTE format('SELECT ($1).%s', entity_type) INTO old_entity_id USING OLD;
IF (old_entity_id = new_entity_id AND OLD.tag = NEW.tag AND OLD.is_upvote != NEW.is_upvote) THEN
-- Case 1: only the vote changed.
PERFORM update_aggregate_tag_count(entity_type, old_entity_id, OLD.tag, (CASE WHEN OLD.is_upvote THEN -2 ELSE 2 END)::SMALLINT);
ELSIF (old_entity_id != new_entity_id OR OLD.tag != NEW.tag OR OLD.is_upvote != NEW.is_upvote) THEN
-- Case 2: the entity, tag, or vote changed.
PERFORM update_aggregate_tag_count(entity_type, old_entity_id, OLD.tag, (CASE WHEN OLD.is_upvote THEN -1 ELSE 1 END)::SMALLINT);
PERFORM update_aggregate_tag_count(entity_type, new_entity_id, NEW.tag, (CASE WHEN NEW.is_upvote THEN 1 ELSE -1 END)::SMALLINT);
PERFORM delete_unused_aggregate_tag(entity_type, old_entity_id, OLD.tag);
END IF;
IF OLD.tag != NEW.tag THEN
UPDATE tag SET ref_count = ref_count - 1 WHERE id = OLD.tag;
UPDATE tag SET ref_count = ref_count + 1 WHERE id = NEW.tag;
END IF;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION update_tag_counts_for_raw_delete()
RETURNS trigger AS $$
DECLARE
entity_type taggable_entity_type;
old_entity_id INTEGER;
BEGIN
entity_type := TG_ARGV[0]::taggable_entity_type;
EXECUTE format('SELECT ($1).%s', entity_type::TEXT) INTO old_entity_id USING OLD;
PERFORM update_aggregate_tag_count(entity_type, old_entity_id, OLD.tag, (CASE WHEN OLD.is_upvote THEN -1 ELSE 1 END)::SMALLINT);
PERFORM delete_unused_aggregate_tag(entity_type, old_entity_id, OLD.tag);
UPDATE tag SET ref_count = ref_count - 1 WHERE id = OLD.tag;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';
COMMIT;

@ -0,0 +1,104 @@
\set ON_ERROR_STOP 1
BEGIN;
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON area_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('area');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON area_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('area');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON area_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('area');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON artist_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('artist');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON artist_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('artist');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON artist_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('artist');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON event_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('event');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON event_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('event');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON event_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('event');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON instrument_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('instrument');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON instrument_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('instrument');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON instrument_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('instrument');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON label_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('label');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON label_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('label');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON label_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('label');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON place_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('place');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON place_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('place');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON place_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('place');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON recording_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('recording');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON recording_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('recording');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON recording_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('recording');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON release_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('release');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON release_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('release');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON release_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('release');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON release_group_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('release_group');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON release_group_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('release_group');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON release_group_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('release_group');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON series_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('series');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON series_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('series');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON series_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('series');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON work_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('work');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON work_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('work');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON work_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('work');
COMMIT;

@ -2,6 +2,7 @@
-- 20210406-mbs-11457.sql
-- 20210526-a_upd_release_event.sql
-- 20210606-mbs-11682.sql
-- 20220207-mbs-12224-mirror.sql
-- 20220218-mbs-12208.sql
-- 20220314-mbs-12252.sql
-- 20220314-mbs-12253.sql
@ -213,6 +214,278 @@ BEGIN
END;
$$ LANGUAGE 'plpgsql';
--------------------------------------------------------------------------------
SELECT '20220207-mbs-12224-mirror.sql';
DELETE FROM area_tag a WHERE NOT EXISTS (
SELECT 1
FROM area_tag_raw r
WHERE r.area = a.area AND r.tag = a.tag
);
UPDATE area_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM area_tag_raw r
WHERE r.area = a.area AND r.tag = a.tag
GROUP BY r.area, r.tag
);
DELETE FROM artist_tag a WHERE NOT EXISTS (
SELECT 1
FROM artist_tag_raw r
WHERE r.artist = a.artist AND r.tag = a.tag
);
UPDATE artist_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM artist_tag_raw r
WHERE r.artist = a.artist AND r.tag = a.tag
GROUP BY r.artist, r.tag
);
DELETE FROM event_tag a WHERE NOT EXISTS (
SELECT 1
FROM event_tag_raw r
WHERE r.event = a.event AND r.tag = a.tag
);
UPDATE event_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM event_tag_raw r
WHERE r.event = a.event AND r.tag = a.tag
GROUP BY r.event, r.tag
);
DELETE FROM instrument_tag a WHERE NOT EXISTS (
SELECT 1
FROM instrument_tag_raw r
WHERE r.instrument = a.instrument AND r.tag = a.tag
);
UPDATE instrument_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM instrument_tag_raw r
WHERE r.instrument = a.instrument AND r.tag = a.tag
GROUP BY r.instrument, r.tag
);
DELETE FROM label_tag a WHERE NOT EXISTS (
SELECT 1
FROM label_tag_raw r
WHERE r.label = a.label AND r.tag = a.tag
);
UPDATE label_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM label_tag_raw r
WHERE r.label = a.label AND r.tag = a.tag
GROUP BY r.label, r.tag
);
DELETE FROM place_tag a WHERE NOT EXISTS (
SELECT 1
FROM place_tag_raw r
WHERE r.place = a.place AND r.tag = a.tag
);
UPDATE place_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM place_tag_raw r
WHERE r.place = a.place AND r.tag = a.tag
GROUP BY r.place, r.tag
);
DELETE FROM recording_tag a WHERE NOT EXISTS (
SELECT 1
FROM recording_tag_raw r
WHERE r.recording = a.recording AND r.tag = a.tag
);
UPDATE recording_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM recording_tag_raw r
WHERE r.recording = a.recording AND r.tag = a.tag
GROUP BY r.recording, r.tag
);
DELETE FROM release_tag a WHERE NOT EXISTS (
SELECT 1
FROM release_tag_raw r
WHERE r.release = a.release AND r.tag = a.tag
);
UPDATE release_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM release_tag_raw r
WHERE r.release = a.release AND r.tag = a.tag
GROUP BY r.release, r.tag
);
DELETE FROM release_group_tag a WHERE NOT EXISTS (
SELECT 1
FROM release_group_tag_raw r
WHERE r.release_group = a.release_group AND r.tag = a.tag
);
UPDATE release_group_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM release_group_tag_raw r
WHERE r.release_group = a.release_group AND r.tag = a.tag
GROUP BY r.release_group, r.tag
);
DELETE FROM series_tag a WHERE NOT EXISTS (
SELECT 1
FROM series_tag_raw r
WHERE r.series = a.series AND r.tag = a.tag
);
UPDATE series_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM series_tag_raw r
WHERE r.series = a.series AND r.tag = a.tag
GROUP BY r.series, r.tag
);
DELETE FROM work_tag a WHERE NOT EXISTS (
SELECT 1
FROM work_tag_raw r
WHERE r.work = a.work AND r.tag = a.tag
);
UPDATE work_tag a SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM work_tag_raw r
WHERE r.work = a.work AND r.tag = a.tag
GROUP BY r.work, r.tag
);
UPDATE tag t SET ref_count = (
(SELECT count(*) FROM area_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM artist_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM event_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM instrument_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM label_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM place_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM recording_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM release_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM release_group_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM series_tag_raw r WHERE r.tag = t.id) +
(SELECT count(*) FROM work_tag_raw r WHERE r.tag = t.id)
);
DELETE FROM tag WHERE ref_count = 0;
CREATE TYPE taggable_entity_type AS ENUM (
'area',
'artist',
'event',
'instrument',
'label',
'place',
'recording',
'release',
'release_group',
'series',
'work'
);
CREATE OR REPLACE FUNCTION update_aggregate_tag_count(entity_type taggable_entity_type, entity_id INTEGER, tag_id INTEGER, count_change SMALLINT)
RETURNS VOID AS $$
BEGIN
-- Insert-or-update the aggregate vote count for the given (entity_id, tag_id).
EXECUTE format(
$SQL$
INSERT INTO %1$I AS agg (%2$I, tag, count)
VALUES ($1, $2, $3)
ON CONFLICT (%2$I, tag) DO UPDATE SET count = agg.count + $3
$SQL$,
entity_type::TEXT || '_tag',
entity_type::TEXT
) USING entity_id, tag_id, count_change;
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION delete_unused_aggregate_tag(entity_type taggable_entity_type, entity_id INTEGER, tag_id INTEGER)
RETURNS VOID AS $$
BEGIN
-- Delete the aggregate tag row for (entity_id, tag_id) if no raw tag pair
-- exists for the same.
--
-- Note that an aggregate vote count of 0 doesn't imply there are no raw
-- tags; it's a sum of all the votes, so it can also mean that there's a
-- downvote for every upvote.
EXECUTE format(
$SQL$
DELETE FROM %1$I
WHERE %2$I = $1
AND tag = $2
AND NOT EXISTS (SELECT 1 FROM %3$I WHERE %2$I = $1 AND tag = $2)
$SQL$,
entity_type::TEXT || '_tag',
entity_type::TEXT,
entity_type::TEXT || '_tag_raw'
) USING entity_id, tag_id;
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION update_tag_counts_for_raw_insert()
RETURNS trigger AS $$
DECLARE
entity_type taggable_entity_type;
new_entity_id INTEGER;
BEGIN
entity_type := TG_ARGV[0]::taggable_entity_type;
EXECUTE format('SELECT ($1).%s', entity_type::TEXT) INTO new_entity_id USING NEW;
PERFORM update_aggregate_tag_count(entity_type, new_entity_id, NEW.tag, (CASE WHEN NEW.is_upvote THEN 1 ELSE -1 END)::SMALLINT);
UPDATE tag SET ref_count = ref_count + 1 WHERE id = NEW.tag;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION update_tag_counts_for_raw_update()
RETURNS trigger AS $$
DECLARE
entity_type taggable_entity_type;
new_entity_id INTEGER;
old_entity_id INTEGER;
BEGIN
entity_type := TG_ARGV[0]::taggable_entity_type;
EXECUTE format('SELECT ($1).%s', entity_type) INTO new_entity_id USING NEW;
EXECUTE format('SELECT ($1).%s', entity_type) INTO old_entity_id USING OLD;
IF (old_entity_id = new_entity_id AND OLD.tag = NEW.tag AND OLD.is_upvote != NEW.is_upvote) THEN
-- Case 1: only the vote changed.
PERFORM update_aggregate_tag_count(entity_type, old_entity_id, OLD.tag, (CASE WHEN OLD.is_upvote THEN -2 ELSE 2 END)::SMALLINT);
ELSIF (old_entity_id != new_entity_id OR OLD.tag != NEW.tag OR OLD.is_upvote != NEW.is_upvote) THEN
-- Case 2: the entity, tag, or vote changed.
PERFORM update_aggregate_tag_count(entity_type, old_entity_id, OLD.tag, (CASE WHEN OLD.is_upvote THEN -1 ELSE 1 END)::SMALLINT);
PERFORM update_aggregate_tag_count(entity_type, new_entity_id, NEW.tag, (CASE WHEN NEW.is_upvote THEN 1 ELSE -1 END)::SMALLINT);
PERFORM delete_unused_aggregate_tag(entity_type, old_entity_id, OLD.tag);
END IF;
IF OLD.tag != NEW.tag THEN
UPDATE tag SET ref_count = ref_count - 1 WHERE id = OLD.tag;
UPDATE tag SET ref_count = ref_count + 1 WHERE id = NEW.tag;
END IF;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION update_tag_counts_for_raw_delete()
RETURNS trigger AS $$
DECLARE
entity_type taggable_entity_type;
old_entity_id INTEGER;
BEGIN
entity_type := TG_ARGV[0]::taggable_entity_type;
EXECUTE format('SELECT ($1).%s', entity_type::TEXT) INTO old_entity_id USING OLD;
PERFORM update_aggregate_tag_count(entity_type, old_entity_id, OLD.tag, (CASE WHEN OLD.is_upvote THEN -1 ELSE 1 END)::SMALLINT);
PERFORM delete_unused_aggregate_tag(entity_type, old_entity_id, OLD.tag);
UPDATE tag SET ref_count = ref_count - 1 WHERE id = OLD.tag;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';
--------------------------------------------------------------------------------
SELECT '20220218-mbs-12208.sql';

@ -4,6 +4,7 @@
-- 20210924-mbs-10327.sql
-- 20211008-mbs-11903.sql
-- 20211216-mbs-12140-12141.sql
-- 20220207-mbs-12224-standalone.sql
-- 20220309-mbs-12241.sql
-- 20220314-mbs-12252-standalone.sql
-- 20220314-mbs-12253-standalone.sql
@ -542,6 +543,109 @@ ALTER TABLE tag
ADD CONSTRAINT control_for_whitespace CHECK (controlled_for_whitespace(name)),
ADD CONSTRAINT only_non_empty CHECK (name != '');
--------------------------------------------------------------------------------
SELECT '20220207-mbs-12224-standalone.sql';
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON area_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('area');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON area_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('area');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON area_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('area');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON artist_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('artist');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON artist_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('artist');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON artist_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('artist');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON event_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('event');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON event_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('event');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON event_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('event');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON instrument_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('instrument');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON instrument_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('instrument');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON instrument_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('instrument');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON label_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('label');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON label_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('label');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON label_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('label');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON place_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('place');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON place_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('place');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON place_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('place');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON recording_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('recording');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON recording_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('recording');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON recording_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('recording');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON release_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('release');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON release_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('release');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON release_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('release');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON release_group_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('release_group');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON release_group_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('release_group');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON release_group_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('release_group');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON series_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('series');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON series_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('series');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON series_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('series');
CREATE TRIGGER update_counts_for_insert AFTER INSERT ON work_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_insert('work');
CREATE TRIGGER update_counts_for_update AFTER UPDATE ON work_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_update('work');
CREATE TRIGGER update_counts_for_delete AFTER DELETE ON work_tag_raw
FOR EACH ROW EXECUTE PROCEDURE update_tag_counts_for_raw_delete('work');
--------------------------------------------------------------------------------
SELECT '20220309-mbs-12241.sql';

@ -232,7 +232,6 @@ sub merge {
my ($self, $new_id, @old_ids) = @_;
my $entity_type = $self->type;
my $assoc_table = $self->tag_table;
my $assoc_table_raw = $self->tag_table . '_raw';
my @ids = ($new_id, @old_ids);
@ -250,24 +249,6 @@ sub merge {
FROM (SELECT DISTINCT ON (editor, tag) editor, tag, is_upvote FROM deleted_tags) s
SQL
$self->c->sql->do(
"DELETE FROM $assoc_table WHERE $entity_type = any(?)",
\@ids
);
my $tags = $self->c->sql->select_single_column_array(
"SELECT DISTINCT tag FROM $assoc_table_raw WHERE $entity_type = ?",
$new_id
);
for my $tag_id (@{$tags}) {
$self->c->sql->do(
"INSERT INTO $assoc_table ($entity_type, tag, count) VALUES (?, ?, 0)",
$new_id, $tag_id
);
$self->_update_count($new_id, $tag_id);
}
return;
}
@ -289,28 +270,6 @@ sub clear {
}
}
sub _update_count {
my ($self, $entity_id, $tag_id) = @_;
my $entity_type = $self->type;
my $assoc_table = $self->tag_table;
my $assoc_table_raw = "${assoc_table}_raw";
return $self->sql->select_single_value(
qq{
UPDATE $assoc_table SET count = (
SELECT sum(CASE WHEN is_upvote THEN 1 ELSE -1 END)
FROM $assoc_table_raw
WHERE $entity_type = \$1 AND tag = \$2
GROUP BY $entity_type, tag
)
WHERE $entity_type = \$1 AND tag = \$2
RETURNING count
},
$entity_id, $tag_id
);
}
sub _vote {
my ($self, $user_id, $entity_id, $tag_name, $is_upvote) = @_;
@ -331,42 +290,17 @@ sub _vote {
$tag_id = $sql->select_single_value('INSERT INTO tag (name) VALUES (?) RETURNING id', $tag_name);
}
# Add raw tag associations, checking for an existing vote first
my $existing_vote = $sql->select_single_value(
"SELECT is_upvote FROM $assoc_table_raw WHERE $entity_type = ? AND tag = ? AND editor = ?",
$entity_id, $tag_id, $user_id
$sql->do(<<~"SQL", $entity_id, $tag_id, $user_id, $is_upvote);
INSERT INTO $assoc_table_raw ($entity_type, tag, editor, is_upvote)
VALUES (?, ?, ?, ?)
ON CONFLICT ($entity_type, tag, editor)
DO UPDATE SET is_upvote = excluded.is_upvote
SQL
# Get the new vote count from the aggregate tag table.
$result->{count} = $sql->select_single_value(
"SELECT count FROM $assoc_table WHERE $entity_type = ? AND tag = ?", $entity_id, $tag_id
);
if (defined $existing_vote) {
$sql->do(
"UPDATE $assoc_table_raw SET is_upvote = ? WHERE $entity_type = ? AND tag = ? AND editor = ?",
$is_upvote, $entity_id, $tag_id, $user_id
);
} else {
$sql->do(
"INSERT INTO $assoc_table_raw ($entity_type, tag, editor, is_upvote) VALUES (?, ?, ?, ?)",
$entity_id, $tag_id, $user_id, $is_upvote
);
}
# Look for the association in the aggregate tags
my $aggregate_exists = $sql->select_single_value(
"SELECT 1 FROM $assoc_table WHERE $entity_type = ? AND tag = ?", $entity_id, $tag_id
);
my $new_count = $new_vote;
if (defined $aggregate_exists) {
# If found, adjust the vote tally
$new_count = $self->_update_count($entity_id, $tag_id);
} else {
# Otherwise add it
$sql->do(
"INSERT INTO $assoc_table ($entity_type, tag, count) VALUES (?, ?, ?)",
$entity_id, $tag_id, $new_vote
);
}
$result->{count} = $new_count;
}, $self->c->sql);
return $result;
@ -409,21 +343,13 @@ sub withdraw {
return;
}
# Delete if no raw votes are left
$was_deleted = $self->sql->select_single_value(
qq{
DELETE FROM $assoc_table
WHERE $entity_type = \$1
AND tag = \$2
AND tag NOT IN (SELECT tag FROM $assoc_table_raw WHERE $entity_type = \$1)
RETURNING 1
},
$entity_id, $tag_id
# Get the new vote count from the aggregate tag table.
my $new_count = $sql->select_single_value(
"SELECT count FROM $assoc_table WHERE $entity_type = ? AND tag = ?", $entity_id, $tag_id
);
unless ($was_deleted) {
# Adjust the vote tally
$result->{count} = $self->_update_count($entity_id, $tag_id);
if (defined $new_count) {
$result->{count} = $new_count;
}
}, $self->c->sql);

@ -106,12 +106,12 @@ test 'artist lookups' => sub {
{
'name' => 'big beat',
'id' => 'aac07ae0-8acf-4249-b5c0-2762b53947a2',
'count' => 3,
'count' => 4,
'disambiguation' => ''
},
{
'id' => '89255676-1f14-4dd8-bbad-fca839d6aff4',
'count' => 7,
'count' => 8,
'disambiguation' => '',
'name' => 'electronic'
},
@ -131,7 +131,7 @@ test 'artist lookups' => sub {
'type' => 'Group',
'tags' => [
{
'count' => 3,
'count' => 4,
'name' => 'big beat'
},
{
@ -144,7 +144,7 @@ test 'artist lookups' => sub {
},
{
'name' => 'electronic',
'count' => 7
'count' => 8
},
{
'count' => 2,

@ -41,10 +41,10 @@ ws_test 'artist lookup with tags, genres, user-tags, and user-genres',
<begin>1989</begin>
</life-span>
<tag-list>
<tag count="3"><name>big beat</name></tag>
<tag count="4"><name>big beat</name></tag>
<tag count="6"><name>british</name></tag>
<tag count="1"><name>dance and electronica</name></tag>
<tag count="7"><name>electronic</name></tag>
<tag count="8"><name>electronic</name></tag>
<tag count="2"><name>electronica</name></tag>
<tag count="1"><name>english</name></tag>
<tag count="1"><name>house</name></tag>
@ -58,8 +58,8 @@ ws_test 'artist lookup with tags, genres, user-tags, and user-genres',
<user-tag><name>electronic</name></user-tag>
</user-tag-list>
<genre-list>
<genre count="3" id="aac07ae0-8acf-4249-b5c0-2762b53947a2"><name>big beat</name></genre>
<genre count="7" id="89255676-1f14-4dd8-bbad-fca839d6aff4"><name>electronic</name></genre>
<genre count="4" id="aac07ae0-8acf-4249-b5c0-2762b53947a2"><name>big beat</name></genre>
<genre count="8" id="89255676-1f14-4dd8-bbad-fca839d6aff4"><name>electronic</name></genre>
<genre count="2" id="53a3cea3-17af-4421-a07a-5824b540aeb5"><name>electronica</name></genre>
<genre count="1" id="a2782cb6-1cd0-477c-a61d-b3f8b42dd1b3"><name>house</name></genre>
</genre-list>

@ -52,7 +52,6 @@ test retest => sub {
my $test = shift;
MusicBrainz::Server::Test->prepare_test_database($test->c, '+tag');
MusicBrainz::Server::Test->prepare_raw_test_database($test->c, '+tag_raw');
my $tag_data = MusicBrainz::Server::Data::EntityTag->new(
c => $test->c, type => 'artist', tag_table => 'artist_tag',

@ -288,7 +288,6 @@ test 'Downvoted tags are preserved post-merge (MBS-8524)' => sub {
INSERT INTO tag (id, name, ref_count) VALUES (1, 'electronic', 0);
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote)
VALUES (3, 1, 1, FALSE);
INSERT INTO artist_tag (artist, count, tag) VALUES (3, -1, 1);
SQL
my $edit = create_edit($c);

325
t/pgtap/tag_counts.sql Normal file

@ -0,0 +1,325 @@
SET search_path = 'musicbrainz', 'public';
BEGIN;
SELECT no_plan();
ALTER TABLE tag DISABLE TRIGGER delete_unused_tag;
INSERT INTO tag (id, name, ref_count)
VALUES (1, 'rock', 0), (2, 'pop', 0), (3, 'bad', 0), (4, 'rock & roll', 0);
INSERT INTO artist (id, gid, name, sort_name)
VALUES (10, '2b7721f6-c25d-4db5-9ebb-ebc6d3c48d0a', 'the tagged', 'tagged, the'),
(11, '540d5370-d8a0-4d5d-96b7-216fd8217ae8', 'the genred', 'genred, the');
INSERT INTO editor (id, name, password, ha1)
VALUES (10, 'tagger1', '', ''), (11, 'tagger2', '', '');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote)
VALUES (10, 10, 3, 't'),
(10, 11, 3, 'f'),
(11, 10, 1, 'f'),
(11, 10, 2, 't'),
(11, 11, 2, 't');
PREPARE all_tags AS
SELECT id, name::TEXT, ref_count
FROM tag
ORDER BY id, name;
PREPARE all_aggregate_artist_tags AS
SELECT artist, tag, count
FROM artist_tag
ORDER BY artist, tag;
SELECT results_eq(
'all_tags',
$$
VALUES -- (id, name, ref_count)
(1::integer, 'rock', 1::integer),
(2::integer, 'pop', 2::integer),
(3::integer, 'bad', 2::integer),
(4::integer, 'rock & roll', 0::integer)
$$
);
SELECT results_eq(
'all_aggregate_artist_tags',
$$
VALUES -- (artist, tag, count)
(10::integer, 3::integer, 0::integer),
(11::integer, 1::integer, -1::integer),
(11::integer, 2::integer, 2::integer)
$$
);
-- Change only the vote (downvote -> upvote).
UPDATE artist_tag_raw
SET is_upvote = 't'
WHERE artist = 10 AND editor = 11 AND tag = 3;
-- artist_tag_raw (artist, editor, tag, is_upvote):
--
-- (10, 10, 3, 't')
-- (10, 11, 3, 't')
-- (11, 10, 1, 'f')
-- (11, 10, 2, 't')
-- (11, 11, 2, 't')
SELECT results_eq(
'all_tags',
$$
VALUES -- (id, name, ref_count)
(1::integer, 'rock', 1::integer),
(2::integer, 'pop', 2::integer),
(3::integer, 'bad', 2::integer),
(4::integer, 'rock & roll', 0::integer)
$$
);
SELECT results_eq(
'all_aggregate_artist_tags',
$$
VALUES -- (artist, tag, count)
(10::integer, 3::integer, 2::integer),
(11::integer, 1::integer, -1::integer),
(11::integer, 2::integer, 2::integer)
$$
);
-- upvote -> downvote
UPDATE artist_tag_raw
SET is_upvote = 'f'
WHERE artist = 11 AND editor = 10 AND tag = 2;
-- artist_tag_raw (artist, editor, tag, is_upvote):
--
-- (10, 10, 3, 't')
-- (10, 11, 3, 't')
-- (11, 10, 1, 'f')
-- (11, 10, 2, 'f')
-- (11, 11, 2, 't')
SELECT results_eq(
'all_tags',
$$
VALUES -- (id, name, ref_count)
(1::integer, 'rock', 1::integer),
(2::integer, 'pop', 2::integer),
(3::integer, 'bad', 2::integer),
(4::integer, 'rock & roll', 0::integer)
$$
);
SELECT results_eq(
'all_aggregate_artist_tags',
$$
VALUES -- (artist, tag, count)
(10::integer, 3::integer, 2::integer),
(11::integer, 1::integer, -1::integer),
(11::integer, 2::integer, 0::integer)
$$
);
-- rock -> rock & roll
UPDATE artist_tag_raw
SET tag = 4
WHERE artist = 11 AND editor = 10 AND tag = 1;
-- artist_tag_raw (artist, editor, tag, is_upvote):
--
-- (10, 10, 3, 't')
-- (10, 11, 3, 't')
-- (11, 10, 2, 'f')
-- (11, 10, 4, 'f')
-- (11, 11, 2, 't')
SELECT results_eq(
'all_tags',
$$
VALUES -- (id, name, ref_count)
(1::integer, 'rock', 0::integer),
(2::integer, 'pop', 2::integer),
(3::integer, 'bad', 2::integer),
(4::integer, 'rock & roll', 1::integer)
$$
);
SELECT results_eq(
'all_aggregate_artist_tags',
$$
VALUES -- (artist, tag, count)
(10::integer, 3::integer, 2::integer),
(11::integer, 2::integer, 0::integer),
(11::integer, 4::integer, -1::integer)
$$
);
-- pop -> rock & roll
UPDATE artist_tag_raw
SET tag = 4
WHERE artist = 11 AND editor = 11 AND tag = 2;
-- artist_tag_raw (artist, editor, tag, is_upvote):
--
-- (10, 10, 3, 't')
-- (10, 11, 3, 't')
-- (11, 10, 2, 'f')
-- (11, 10, 4, 'f')
-- (11, 11, 4, 't')
SELECT results_eq(
'all_tags',
$$
VALUES -- (id, name, ref_count)
(1::integer, 'rock', 0::integer),
(2::integer, 'pop', 1::integer),
(3::integer, 'bad', 2::integer),
(4::integer, 'rock & roll', 2::integer)
$$
);
SELECT results_eq(
'all_aggregate_artist_tags',
$$
VALUES -- (artist, tag, count)
(10::integer, 3::integer, 2::integer),
(11::integer, 2::integer, -1::integer),
(11::integer, 4::integer, 0::integer)
$$
);
-- artist 11 -> artist 10
UPDATE artist_tag_raw
SET artist = 10
WHERE artist = 11 AND editor = 10 AND tag = 2;
-- artist_tag_raw (artist, editor, tag, is_upvote):
--
-- (10, 10, 2, 'f')
-- (10, 10, 3, 't')
-- (10, 11, 3, 't')
-- (11, 10, 4, 'f')
-- (11, 11, 4, 't')
SELECT results_eq(
'all_tags',
$$
VALUES -- (id, name, ref_count)
(1::integer, 'rock', 0::integer),
(2::integer, 'pop', 1::integer),
(3::integer, 'bad', 2::integer),
(4::integer, 'rock & roll', 2::integer)
$$
);
SELECT results_eq(
'all_aggregate_artist_tags',
$$
VALUES -- (artist, tag, count)
(10::integer, 2::integer, -1::integer),
(10::integer, 3::integer, 2::integer),
(11::integer, 4::integer, 0::integer)
$$
);
-- Update artist, tag, and is_upvote all at once.
UPDATE artist_tag_raw
SET artist = 11, tag = 1, is_upvote = 'f'
WHERE artist = 10 AND editor = 11 AND tag = 3;
-- artist_tag_raw (artist, editor, tag, is_upvote):
--
-- (10, 10, 2, 'f')
-- (10, 10, 3, 't')
-- (11, 10, 4, 'f')
-- (11, 11, 1, 'f')
-- (11, 11, 4, 't')
SELECT results_eq(
'all_tags',
$$
VALUES -- (id, name, ref_count)
(1::integer, 'rock', 1::integer),
(2::integer, 'pop', 1::integer),
(3::integer, 'bad', 1::integer),
(4::integer, 'rock & roll', 2::integer)
$$
);
SELECT results_eq(
'all_aggregate_artist_tags',
$$
VALUES -- (artist, tag, count)
(10::integer, 2::integer, -1::integer),
(10::integer, 3::integer, 1::integer),
(11::integer, 1::integer, -1::integer),
(11::integer, 4::integer, 0::integer)
$$
);
-- Delete editor 11's tags.
DELETE FROM artist_tag_raw WHERE editor = 11;
-- artist_tag_raw (artist, editor, tag, is_upvote):
--
-- (10, 10, 2, 'f')
-- (10, 10, 3, 't')
-- (11, 10, 4, 'f')
SELECT results_eq(
'all_tags',
$$
VALUES -- (id, name, ref_count)
(1::integer, 'rock', 0::integer),
(2::integer, 'pop', 1::integer),
(3::integer, 'bad', 1::integer),
(4::integer, 'rock & roll', 1::integer)
$$
);
SELECT results_eq(
'all_aggregate_artist_tags',
$$
VALUES -- (artist, tag, count)
(10::integer, 2::integer, -1::integer),
(10::integer, 3::integer, 1::integer),
(11::integer, 4::integer, -1::integer)
$$
);
-- Move editor 10's tags to editor 11, just to see that the counts remain the
-- same. (This shouldn't happen in practice.)
UPDATE artist_tag_raw SET editor = 11;
-- artist_tag_raw (artist, editor, tag, is_upvote):
--
-- (10, 11, 2, 'f')
-- (10, 11, 3, 't')
-- (11, 11, 4, 'f')
SELECT results_eq(
'all_tags',
$$
VALUES -- (id, name, ref_count)
(1::integer, 'rock', 0::integer),
(2::integer, 'pop', 1::integer),
(3::integer, 'bad', 1::integer),
(4::integer, 'rock & roll', 1::integer)
$$
);
SELECT results_eq(
'all_aggregate_artist_tags',
$$
VALUES -- (artist, tag, count)
(10::integer, 2::integer, -1::integer),
(10::integer, 3::integer, 1::integer),
(11::integer, 4::integer, -1::integer)
$$
);
ALTER TABLE tag ENABLE TRIGGER delete_unused_tag;
SELECT finish();
ROLLBACK;

@ -1,4 +1,3 @@
-- Automatically generated, do not edit.
-- release ceb0edd0-550c-4543-8e83-edc92f8ed70c
SET client_min_messages TO 'warning';
@ -12,8 +11,6 @@ INSERT INTO musicbrainz.editor (id, name, privs, email, website, bio, member_sin
(58244, 'Bitmap', 0, '', NULL, NULL, '2004-08-02 00:10:36.760201+00', '2010-07-11 15:25:29.450044+00', '2019-02-12 07:28:15.904198+00', '2019-02-12 04:24:39.711348+00', NULL, NULL, NULL, '{CLEARTEXT}mb', '0aabee37a3132c87fb2927c91c1799dc', '0');
INSERT INTO musicbrainz.tag (id, name, ref_count) VALUES
(1440, 'psychobilly', 320);
INSERT INTO musicbrainz.artist_tag (artist, tag, count, last_updated) VALUES
(1744798, 1440, 1, '2019-02-12 04:16:25.750749+00');
INSERT INTO musicbrainz.artist_tag_raw (artist, editor, tag, is_upvote) VALUES
(1744798, 58244, 1440, '1');
INSERT INTO musicbrainz.artist_credit (id, name, artist_count, ref_count, created) VALUES
@ -24,8 +21,6 @@ INSERT INTO musicbrainz.artist (id, gid, name, sort_name, begin_date_year, begin
(1744799, '561e53a1-9ae6-4d85-95c0-a39b028eabe4', 'Frances Jones', 'Jones, Frances', NULL, NULL, NULL, NULL, NULL, NULL, 1, NULL, 1, '', 0, '2019-02-12 04:11:38.857794+00', '0', NULL, NULL);
INSERT INTO musicbrainz.tag (id, name, ref_count) VALUES
(714, 'britpop', 236);
INSERT INTO musicbrainz.artist_tag (artist, tag, count, last_updated) VALUES
(1744799, 714, 1, '2019-02-12 04:15:51.75995+00');
INSERT INTO musicbrainz.artist_tag_raw (artist, editor, tag, is_upvote) VALUES
(1744799, 58244, 714, '1');
INSERT INTO musicbrainz.artist_credit (id, name, artist_count, ref_count, created) VALUES
@ -37,8 +32,6 @@ INSERT INTO musicbrainz.release_group (id, gid, name, artist_credit, type, comme
(2069046, '9792a49e-f1e1-4848-8546-82bae03206f6', 'Greatest Hits', 2319049, NULL, '', 0, '2019-02-12 04:14:46.076201+00');
INSERT INTO musicbrainz.tag (id, name, ref_count) VALUES
(32086, 'doo-wop', 3);
INSERT INTO musicbrainz.release_group_tag (release_group, tag, count, last_updated) VALUES
(2069046, 32086, 1, '2019-02-12 07:13:05.37894+00');
INSERT INTO musicbrainz.release_group_tag_raw (release_group, editor, tag, is_upvote) VALUES
(2069046, 58244, 32086, '1');
INSERT INTO musicbrainz.release (id, gid, name, artist_credit, release_group, status, packaging, language, script, barcode, comment, edits_pending, quality, last_updated) VALUES
@ -49,8 +42,6 @@ INSERT INTO musicbrainz.artist (id, gid, name, sort_name, begin_date_year, begin
(1744801, '9084ad69-7e81-44f9-a195-a522a9b7b08b', 'Leslie Rice', 'Rice, Leslie', NULL, NULL, NULL, NULL, NULL, NULL, 4, NULL, 3, '', 0, '2019-02-12 04:12:10.971646+00', '0', NULL, NULL);
INSERT INTO musicbrainz.tag (id, name, ref_count) VALUES
(117022, 'post-classical', 0);
INSERT INTO musicbrainz.artist_tag (artist, tag, count, last_updated) VALUES
(1744801, 117022, 1, '2019-02-12 04:16:11.591278+00');
INSERT INTO musicbrainz.artist_tag_raw (artist, editor, tag, is_upvote) VALUES
(1744801, 58244, 117022, '1');
INSERT INTO musicbrainz.artist_credit (id, name, artist_count, ref_count, created) VALUES
@ -63,16 +54,12 @@ INSERT INTO musicbrainz.recording (id, gid, name, artist_credit, length, comment
(23684118, 'a3494070-d758-48d4-84c2-80948f5a810b', '10 hours of horn', 2319052, 36000000, '', 0, '2019-02-12 05:15:49.014985+00', '0');
INSERT INTO musicbrainz.tag (id, name, ref_count) VALUES
(30470, 'freak folk', 3);
INSERT INTO musicbrainz.recording_tag (recording, tag, count, last_updated) VALUES
(23684118, 30470, 1, '2019-02-12 07:13:51.123953+00');
INSERT INTO musicbrainz.recording_tag_raw (recording, editor, tag, is_upvote) VALUES
(23684118, 58244, 30470, '1');
INSERT INTO musicbrainz.artist (id, gid, name, sort_name, begin_date_year, begin_date_month, begin_date_day, end_date_year, end_date_month, end_date_day, type, area, gender, comment, edits_pending, last_updated, ended, begin_area, end_area) VALUES
(1744800, '95ffd873-9901-4ebd-b07d-eb1fe4485baf', 'Lavone Grimm', 'Grimm, Lavone', NULL, NULL, NULL, NULL, NULL, NULL, 1, NULL, 3, '', 0, '2019-02-12 04:05:04.571866+00', '0', NULL, NULL);
INSERT INTO musicbrainz.tag (id, name, ref_count) VALUES
(1434, 'blackened death metal', 13);
INSERT INTO musicbrainz.artist_tag (artist, tag, count, last_updated) VALUES
(1744800, 1434, 1, '2019-02-12 04:16:01.949144+00');
INSERT INTO musicbrainz.artist_tag_raw (artist, editor, tag, is_upvote) VALUES
(1744800, 58244, 1434, '1');
INSERT INTO musicbrainz.artist_credit (id, name, artist_count, ref_count, created) VALUES
@ -85,8 +72,6 @@ INSERT INTO musicbrainz.track (id, gid, recording, medium, position, number, nam
(26817940, 'ee78f26a-f14c-44b4-95a6-b3a312985f30', 23684118, 2486082, 1, '1', '10 hours of horn', 2319051, 36000000, 0, '2019-02-12 05:15:19.278941+00', '0');
INSERT INTO musicbrainz.tag (id, name, ref_count) VALUES
(1137, 'hard bop', 192);
INSERT INTO musicbrainz.release_tag (release, tag, count, last_updated) VALUES
(2299278, 1137, 1, '2019-02-12 07:11:54.439327+00');
INSERT INTO musicbrainz.release_tag_raw (release, editor, tag, is_upvote) VALUES
(2299278, 58244, 1137, '1');
INSERT INTO musicbrainz.genre (id, gid, name) VALUES (11, '8a14f570-7297-438d-996d-8797f9b8cfcc', 'psychobilly');

@ -4,16 +4,32 @@ INSERT INTO artist (id, gid, name, sort_name)
VALUES (3, 'e2a083a9-9942-4d6e-b4d2-8397320b95f7', 'Artist 1', 'Artist 1'),
(4, '2fed031c-0e89-406e-b9f0-3d192637907a', 'Artist 2', 'Artist 2');
INSERT INTO tag (id, name) VALUES
(1, 'musical'),
(2, 'rock'),
(3, 'jazz'),
(4, 'world music');
INSERT INTO tag (id, name)
VALUES (1, 'musical'),
(2, 'rock'),
(3, 'jazz'),
(4, 'world music');
INSERT INTO artist_tag (tag, artist, count) VALUES
(1, 3, 1),
(2, 3, 3),
(1, 4, 5),
(2, 4, 3),
(3, 4, 2),
(4, 4, 1);
INSERT INTO editor (id, name, password, ha1)
VALUES (11, 'editor1', '{CLEARTEXT}password', '0e5b1cce99adc89b535a3c6523c5410a'),
(12, 'editor2', '{CLEARTEXT}password', '9ab932d00c88daf4a3ccf3a25e00f977'),
(13, 'editor3', '{CLEARTEXT}password', '8226c71cd2dd007dc924910793b8ca83'),
(14, 'editor4', '{CLEARTEXT}password', 'f0ab22e1a22cb1e60fea481f812450cb'),
(15, 'editor5', '{CLEARTEXT}password', '3df132c9df92678048a6b25c5ad751ef');
INSERT INTO artist_tag_raw (tag, artist, editor)
VALUES (1, 3, 11),
(2, 3, 12),
(2, 3, 13),
(2, 3, 14),
(1, 4, 11),
(1, 4, 12),
(1, 4, 13),
(1, 4, 14),
(1, 4, 15),
(2, 4, 11),
(2, 4, 12),
(2, 4, 13),
(3, 4, 14),
(3, 4, 15),
(4, 4, 12);

@ -1,29 +0,0 @@
SET client_min_messages TO 'WARNING';
INSERT INTO editor (id, name, password, ha1) VALUES (11, 'editor1', '{CLEARTEXT}password', '0e5b1cce99adc89b535a3c6523c5410a'), (12, 'editor2', '{CLEARTEXT}password', '9ab932d00c88daf4a3ccf3a25e00f977'), (13, 'editor3', '{CLEARTEXT}password', '8226c71cd2dd007dc924910793b8ca83'), (14, 'editor4', '{CLEARTEXT}password', 'f0ab22e1a22cb1e60fea481f812450cb'), (15, 'editor5', '{CLEARTEXT}password', '3df132c9df92678048a6b25c5ad751ef');
INSERT INTO artist_tag_raw (tag, artist, editor) VALUES
(1, 3, 11),
(2, 3, 12),
(2, 3, 13),
(2, 3, 14),
(1, 4, 11),
(1, 4, 12),
(1, 4, 13),
(1, 4, 14),
(1, 4, 15),
(2, 4, 11),
(2, 4, 12),
(2, 4, 13),
(3, 4, 14),
(3, 4, 15),
(4, 4, 12);

@ -1,4 +1,3 @@
-- Generated by ../../script/webservice_test_data.pl
\set ON_ERROR_STOP 1
SET client_min_messages TO 'warning';
@ -18,6 +17,18 @@ INSERT INTO area (id, gid, name, type) VALUES
INSERT INTO country_area (area) VALUES ( 13), ( 81), (107), (150), (221), (222), (241);
INSERT INTO iso_3166_1 (area, code) VALUES ( 13, 'AU'), ( 81, 'DE'), (107, 'JP'), (150, 'NL'), (221, 'GB'), (222, 'US'), (241, 'XE');
-- Editors
INSERT INTO editor (id, name, password, ha1, email, email_confirm_date)
VALUES (95821, 'the-anti-kuno', '{CLEARTEXT}notreally', '79237ef54f6d3b8711030c0d6d5939a0', 'foo@example.com', now()),
(100000001, 'a tagger', '', '', '', now()),
(100000002, 'b tagger', '', '', '', now()),
(100000003, 'c tagger', '', '', '', now()),
(100000004, 'd tagger', '', '', '', now()),
(100000005, 'e tagger', '', '', '', now()),
(100000006, 'f tagger', '', '', '', now()),
(100000007, 'g tagger', '', '', '', now());
-- URLs
INSERT INTO url (id, edits_pending, gid, last_updated, url) VALUES (24048, 0, '2665145a-4474-4c57-97d1-c0299048177a', '2011-01-18 16:23:38+00', 'http://www.mop2001.com/bag.html');
@ -1191,236 +1202,63 @@ INSERT INTO genre (id, gid, name) VALUES (8, 'aac07ae0-8acf-4249-b5c0-2762b53947
INSERT INTO genre (id, gid, name) VALUES (9, 'a2782cb6-1cd0-477c-a61d-b3f8b42dd1b3', 'house');
INSERT INTO genre (id, gid, name) VALUES (10, '18b010d7-7d85-4445-a4a8-1889a4688308', 'glitch');
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (242, 3, '2011-01-18 15:21:33.71184+00', 34);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (242, 1, '2011-01-18 15:21:33.71184+00', 77);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (242, 1, '2011-01-18 15:21:33.71184+00', 1);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (242, 1, '2011-01-18 15:21:33.71184+00', 237);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (242, 1, '2011-01-18 15:21:33.71184+00', 1391);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (242, 1, '2011-01-18 15:21:33.71184+00', 1974);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (242, 1, '2011-01-18 15:21:33.71184+00', 4666);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (242, 6, '2011-01-18 15:21:33.71184+00', 171);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (242, 2, '2011-01-18 15:21:33.71184+00', 559);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (242, 7, '2011-01-18 15:21:33.71184+00', 11);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (242, 1, '2011-01-18 15:21:33.71184+00', 2105);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (9496, 1, '2011-01-18 15:21:33.71184+00', 558);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (9496, 1, '2011-01-18 15:21:33.71184+00', 741);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (9496, 1, '2011-01-18 15:21:33.71184+00', 1354);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (9496, 1, '2011-01-18 15:21:33.71184+00', 1355);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (9496, 1, '2011-01-18 15:21:33.71184+00', 104);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (9496, 1, '2011-01-18 15:21:33.71184+00', 502);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (9496, 1, '2011-01-18 15:21:33.71184+00', 19);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (11545, 1, '2011-01-18 15:21:33.71184+00', 237);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (11545, 1, '2011-01-18 15:21:33.71184+00', 171);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (11545, 1, '2011-01-18 15:21:33.71184+00', 1391);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (11545, 1, '2011-01-18 15:21:33.71184+00', 1661);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (11545, 1, '2011-01-18 15:21:33.71184+00', 559);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (11545, 1, '2011-01-18 15:21:33.71184+00', 11);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (11545, 1, '2011-01-18 15:21:33.71184+00', 1032);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (265420, 1, '2011-01-18 15:21:33.71184+00', 114);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (265420, 1, '2011-01-18 15:21:33.71184+00', 1998);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (265420, 1, '2011-01-18 15:21:33.71184+00', 1997);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (265420, 1, '2011-01-18 15:21:33.71184+00', 27737);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398438, 1, '2011-01-18 15:21:33.71184+00', 3253);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398438, 1, '2011-01-18 15:21:33.71184+00', 3254);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398438, 1, '2011-01-18 15:21:33.71184+00', 3255);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398438, 1, '2011-01-18 15:21:33.71184+00', 3256);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398438, 1, '2011-01-18 15:21:33.71184+00', 3257);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398438, 1, '2011-01-18 15:21:33.71184+00', 6542);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398438, 1, '2011-01-18 15:21:33.71184+00', 22032);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398438, 1, '2011-01-18 15:21:33.71184+00', 22033);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398438, 1, '2011-01-18 15:21:33.71184+00', 3875);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398438, 1, '2011-01-18 15:21:33.71184+00', 6662);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398438, 1, '2011-01-18 15:21:33.71184+00', 6543);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398438, 1, '2011-01-18 15:21:33.71184+00', 3884);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 6669);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 3253);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 3872);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 3859);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 3254);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 6650);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 3873);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 3875);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 2726);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 6670);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 3876);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 3884);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 6671);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 3885);
INSERT INTO artist_tag (artist, count, last_updated, tag) VALUES (398598, 1, '2011-01-18 15:21:33.71184+00', 6672);
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 95821, 34, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000001, 34, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000002, 34, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000003, 34, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000001, 77, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000001, 1, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000001, 237, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000001, 1391, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000001, 1974, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000001, 4666, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000001, 171, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000002, 171, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000003, 171, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000004, 171, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000005, 171, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000006, 171, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000001, 559, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000002, 559, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 95821, 11, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000001, 11, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000002, 11, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000003, 11, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000004, 11, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000005, 11, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000006, 11, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000007, 11, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 100000001, 2105, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 95821, 741, 'f');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (9496, 100000001, 558, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (9496, 100000001, 741, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (9496, 100000001, 1354, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (9496, 100000001, 1355, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (9496, 100000001, 104, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (9496, 100000001, 502, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (9496, 100000001, 19, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (11545, 100000001, 237, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (11545, 100000001, 171, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (11545, 100000001, 1391, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (11545, 100000001, 1661, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (11545, 100000001, 559, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (11545, 100000001, 11, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (11545, 100000001, 1032, 't');
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 597897, 11);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 597897, 1522);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (2, '2011-01-18 15:46:28.148085+00', 597897, 30);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 326504, 29329);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 724150, 559);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (5, '2011-01-18 15:46:28.148085+00', 724150, 11);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (4, '2011-01-18 15:46:28.148085+00', 724150, 1282);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 724150, 800);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 724150, 4666);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 724150, 590);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (2, '2011-01-18 15:46:28.148085+00', 724150, 545);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 724150, 1030);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (2, '2011-01-18 15:46:28.148085+00', 724150, 34);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3881);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3258);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3880);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3882);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3872);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 11);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3883);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3259);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3859);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3886);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3873);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3876);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3857);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 642);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3871);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3870);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3877);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3884);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3254);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3887);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3885);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3253);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3879);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3878);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3874);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 703316, 3875);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 772397, 6673);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 772397, 6679);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 772397, 6676);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 772397, 3862);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 772397, 1051);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 772397, 3873);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 772397, 3884);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 772397, 6675);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 772397, 6677);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 772397, 6678);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 772397, 6674);
INSERT INTO release_group_tag (count, last_updated, release_group, tag) VALUES (1, '2011-01-18 15:46:28.148085+00', 377462, 114);
INSERT INTO release_group_tag_raw (release_group, editor, tag, is_upvote) VALUES (326504, 100000001, 29329, 't');
INSERT INTO release_group_tag_raw (release_group, editor, tag, is_upvote) VALUES (597897, 100000001, 11, 't');
INSERT INTO release_group_tag_raw (release_group, editor, tag, is_upvote) VALUES (597897, 100000001, 1522, 't');
INSERT INTO release_group_tag_raw (release_group, editor, tag, is_upvote) VALUES (597897, 100000001, 30, 't');
INSERT INTO release_group_tag_raw (release_group, editor, tag, is_upvote) VALUES (597897, 100000002, 30, 't');
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 187, '2011-01-18 15:21:33.71184+00', 748);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 187, '2011-01-18 15:21:33.71184+00', 273);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 187, '2011-01-18 15:21:33.71184+00', 111);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 187, '2011-01-18 15:21:33.71184+00', 20);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 95, '2011-01-18 15:21:33.71184+00', 1391);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (2, 95, '2011-01-18 15:21:33.71184+00', 237);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 95, '2011-01-18 15:21:33.71184+00', 20);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 95, '2011-01-18 15:21:33.71184+00', 1190);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 95, '2011-01-18 15:21:33.71184+00', 280);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (2, 95, '2011-01-18 15:21:33.71184+00', 171);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 95, '2011-01-18 15:21:33.71184+00', 11);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 33, '2011-01-18 15:21:33.71184+00', 8383);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 33, '2011-01-18 15:21:33.71184+00', 748);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 33, '2011-01-18 15:21:33.71184+00', 71);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 33, '2011-01-18 15:21:33.71184+00', 273);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 33, '2011-01-18 15:21:33.71184+00', 111);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 33, '2011-01-18 15:21:33.71184+00', 1246);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 33, '2011-01-18 15:21:33.71184+00', 343);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 33, '2011-01-18 15:21:33.71184+00', 271);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 33, '2011-01-18 15:21:33.71184+00', 7);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 395, '2011-01-18 15:21:33.71184+00', 743);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 395, '2011-01-18 15:21:33.71184+00', 25514);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 395, '2011-01-18 15:21:33.71184+00', 88);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 395, '2011-01-18 15:21:33.71184+00', 1887);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 395, '2011-01-18 15:21:33.71184+00', 2147);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 395, '2011-01-18 15:21:33.71184+00', 273);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 36456, '2011-01-18 15:21:33.71184+00', 748);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 36456, '2011-01-18 15:21:33.71184+00', 7913);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 36456, '2011-01-18 15:21:33.71184+00', 273);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 36456, '2011-01-18 15:21:33.71184+00', 111);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 36456, '2011-01-18 15:21:33.71184+00', 7914);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 3857);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 3859);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 3872);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 3254);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 3874);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 3258);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 6543);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 3403);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 6622);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 3877);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 6544);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 6542);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 3253);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 5221);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 3259);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 3933, '2011-01-18 15:21:33.71184+00', 3884);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 381, '2011-01-18 15:21:33.71184+00', 114);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 46, '2011-01-18 15:21:33.71184+00', 1032);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 46, '2011-01-18 15:21:33.71184+00', 1604);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 46, '2011-01-18 15:21:33.71184+00', 545);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 46, '2011-01-18 15:21:33.71184+00', 559);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 46, '2011-01-18 15:21:33.71184+00', 1661);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (2, 46, '2011-01-18 15:21:33.71184+00', 1391);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (2, 46, '2011-01-18 15:21:33.71184+00', 205);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (2, 46, '2011-01-18 15:21:33.71184+00', 11);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (2, 46, '2011-01-18 15:21:33.71184+00', 237);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 46, '2011-01-18 15:21:33.71184+00', 166);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 46, '2011-01-18 15:21:33.71184+00', 280);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (3, 46, '2011-01-18 15:21:33.71184+00', 171);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 46, '2011-01-18 15:21:33.71184+00', 1063);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 46, '2011-01-18 15:21:33.71184+00', 284);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 124, '2011-01-18 15:21:33.71184+00', 748);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 124, '2011-01-18 15:21:33.71184+00', 537);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 124, '2011-01-18 15:21:33.71184+00', 273);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 124, '2011-01-18 15:21:33.71184+00', 111);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 124, '2011-01-18 15:21:33.71184+00', 16);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 124, '2011-01-18 15:21:33.71184+00', 49);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 124, '2011-01-18 15:21:33.71184+00', 518);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 124, '2011-01-18 15:21:33.71184+00', 1079);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 124, '2011-01-18 15:21:33.71184+00', 284);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 132, '2011-01-18 15:21:33.71184+00', 237);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 132, '2011-01-18 15:21:33.71184+00', 171);
INSERT INTO label_tag (count, label, last_updated, tag) VALUES (1, 132, '2011-01-18 15:21:33.71184+00', 1391);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 6750266, 30);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 8509233, 33017);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, NULL, 4525123, 558);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, NULL, 4525010, 741);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, NULL, 4525011, 1354);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 1062699, 559);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 1062699, 1282);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 1062699, 11);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 1353886, 11);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 1353886, 559);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (3, '2011-01-18 15:56:00.408782+00', 1353886, 1282);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 1353886, 545);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726277, 11);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726277, 1282);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 2726277, 559);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726271, 1282);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 2726271, 11);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726274, 11);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726274, 1282);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 2726274, 559);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 15296, 559);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 15296, 545);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 2726276, 559);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726276, 1282);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726276, 11);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726281, 1282);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 2726281, 559);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726281, 11);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 2726275, 559);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726275, 1282);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726275, 11);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726272, 1282);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 2726272, 559);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726272, 11);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726278, 1282);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 2726278, 559);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (3, '2011-01-18 15:56:00.408782+00', 2726278, 11);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726280, 1282);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (2, '2011-01-18 15:56:00.408782+00', 2726280, 11);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 4844122, 11);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 4844122, 559);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 4844123, 11);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 4844123, 559);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 7905440, 3884);
INSERT INTO recording_tag (count, last_updated, recording, tag) VALUES (1, '2011-01-18 15:56:00.408782+00', 7905440, 6672);
INSERT INTO label_tag_raw (label, editor, tag, is_upvote) VALUES (132, 100000001, 237, 't');
INSERT INTO label_tag_raw (label, editor, tag, is_upvote) VALUES (132, 100000001, 171, 't');
INSERT INTO label_tag_raw (label, editor, tag, is_upvote) VALUES (132, 100000001, 1391, 't');
INSERT INTO recording_tag_raw (recording, editor, tag, is_upvote) VALUES (4525010, 100000001, 741, 't');
INSERT INTO recording_tag_raw (recording, editor, tag, is_upvote) VALUES (4525011, 100000001, 1354, 't');
INSERT INTO recording_tag_raw (recording, editor, tag, is_upvote) VALUES (4525123, 100000001, 558, 't');
INSERT INTO recording_tag_raw (recording, editor, tag, is_upvote) VALUES (6750266, 100000001, 30, 't');
-- CDTOC/medium_cdtoc/etc.
@ -1525,8 +1363,6 @@ INSERT INTO medium_cdtoc (cdtoc, edits_pending, id, last_updated, medium) VALUES
-- Assorted
INSERT INTO editor (id, name, password, ha1, email, email_confirm_date) VALUES (95821, 'the-anti-kuno', '{CLEARTEXT}notreally', '79237ef54f6d3b8711030c0d6d5939a0', 'foo@example.com', now());
INSERT INTO edit (autoedit, close_time, editor, expire_time, id, language, open_time, quality, status, type) VALUES (0, NULL, 95821, '2013-04-16 17:42:38.063723+00', 1, NULL, '2013-04-02 17:42:38.063723+00', 1, 2, 314);
INSERT INTO edit_data (edit, data) VALUES (1, '{}');
@ -1812,10 +1648,6 @@ INSERT INTO editor_collection_series (collection, series) VALUES (20, 25);
INSERT INTO editor_collection_work (collection, work) VALUES (21, 12488154);
INSERT INTO editor_collection_work (collection, work) VALUES (22, 12488155);
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 95821, 11, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 95821, 34, 't');
INSERT INTO artist_tag_raw (artist, editor, tag, is_upvote) VALUES (242, 95821, 741, 'f');
UPDATE medium
SET track_count = tc.count
FROM (SELECT count(id),medium FROM track GROUP BY medium) tc

@ -106,6 +106,7 @@
"mirror": ["20210406-mbs-11457.sql",
"20210526-a_upd_release_event.sql",
"20210606-mbs-11682.sql",
"20220207-mbs-12224-mirror.sql",
"20220218-mbs-12208.sql",
"20220314-mbs-12252.sql",
"20220314-mbs-12253.sql",
@ -120,6 +121,7 @@
"20210924-mbs-10327.sql",
"20211008-mbs-11903.sql",
"20211216-mbs-12140-12141.sql",
"20220207-mbs-12224-standalone.sql",
"20220309-mbs-12241.sql",
"20220314-mbs-12252-standalone.sql",
"20220314-mbs-12253-standalone.sql",