summaryrefslogtreecommitdiff
path: root/util/sql/func.sql
diff options
context:
space:
mode:
Diffstat (limited to 'util/sql/func.sql')
-rw-r--r--util/sql/func.sql89
1 files changed, 41 insertions, 48 deletions
diff --git a/util/sql/func.sql b/util/sql/func.sql
index cdf1b605..57e0b43f 100644
--- a/util/sql/func.sql
+++ b/util/sql/func.sql
@@ -129,39 +129,32 @@ BEGIN
DROP INDEX IF EXISTS tags_vn_inherit_tag_vid;
TRUNCATE tags_vn_inherit;
-- populate tags_vn_inherit
- INSERT INTO tags_vn_inherit
- -- All votes for all tags, including votes inherited by child tags if the
- -- parent tag itself does not have any votes.
- -- (also includes non-searchable tags, because they could have a searchable tag as parent)
- WITH RECURSIVE tags_vn_all(lvl, tag, vid, uid, vote, spoiler, defaultspoil, searchable) AS (
- SELECT 15, tv.tag, tv.vid, tv.uid, tv.vote, tv.spoiler, t.defaultspoil, true
- FROM tags_vn tv
- JOIN tags t ON t.id = tv.tag
- WHERE NOT tv.ignore
- UNION ALL
- SELECT lvl-1, tp.parent, ta.vid, ta.uid, ta.vote, ta.spoiler, t.defaultspoil, t.searchable
- FROM tags_vn_all ta
- JOIN tags_parents tp ON tp.tag = ta.tag
- JOIN tags t ON t.id = tp.parent
- WHERE t.state = 2
- AND ta.lvl > 0
- AND NOT EXISTS(SELECT 1 FROM tags_vn tv WHERE tv.tag = tp.parent AND tv.vid = ta.vid)
+ INSERT INTO tags_vn_inherit (tag, vid, rating, spoiler)
+ -- Group votes to generate a list of directly-upvoted (vid, tag) pairs.
+ -- This is essentually the same as the tag listing on VN pages.
+ WITH RECURSIVE t_avg(tag, vid, vote, spoiler) AS (
+ SELECT tv.tag, tv.vid, AVG(tv.vote)::real, CASE WHEN COUNT(tv.spoiler) = 0 THEN MIN(t.defaultspoil) ELSE AVG(tv.spoiler)::real END
+ FROM tags_vn tv
+ JOIN tags t ON t.id = tv.tag
+ WHERE NOT tv.ignore AND t.state = 2
+ AND vid NOT IN(SELECT id FROM vn WHERE hidden)
+ GROUP BY tv.tag, tv.vid
+ HAVING AVG(tv.vote) > 0
+ -- Add parent tags
+ ), t_all(lvl, tag, vid, vote, spoiler) AS (
+ SELECT 15, * FROM t_avg
+ UNION ALL
+ SELECT ta.lvl-1, tp.parent, ta.vid, ta.vote, ta.spoiler
+ FROM t_all ta
+ JOIN tags_parents tp ON tp.tag = ta.tag
+ WHERE ta.lvl > 0
)
- -- grouped by (tag, vid)
- SELECT tag, vid, COUNT(uid) AS users, AVG(vote)::real AS rating,
- (CASE WHEN COUNT(spoiler) = 0 THEN defaultspoil
- WHEN AVG(spoiler) > 1.3 THEN 2
- WHEN AVG(spoiler) > 0.4 THEN 1 ELSE 0
- END)::smallint AS spoiler
- FROM (
- -- grouped by (tag, vid, uid), so only one user votes on one parent tag per VN entry (also removing unsearchable tags)
- SELECT tag, vid, uid, MAX(vote)::real, AVG(spoiler)::real, defaultspoil
- FROM tags_vn_all
- WHERE searchable
- GROUP BY tag, vid, uid, defaultspoil
- ) AS t(tag, vid, uid, vote, spoiler, defaultspoil)
- GROUP BY tag, vid, defaultspoil
- HAVING AVG(vote) > 0;
+ -- Merge
+ SELECT tag, vid, AVG(vote)
+ , (CASE WHEN MIN(spoiler) > 1.3 THEN 2 WHEN MIN(spoiler) > 0.4 THEN 1 ELSE 0 END)::smallint
+ FROM t_all
+ WHERE tag IN(SELECT id FROM tags WHERE searchable)
+ GROUP BY tag, vid;
-- recreate index
CREATE INDEX tags_vn_inherit_tag_vid ON tags_vn_inherit (tag, vid);
-- and update the VN count in the tags table
@@ -174,36 +167,36 @@ $$ LANGUAGE plpgsql SECURITY DEFINER;
-- recalculate traits_chars
CREATE OR REPLACE FUNCTION traits_chars_calc() RETURNS void AS $$
BEGIN
+ DROP INDEX IF EXISTS traits_chars_tid;
TRUNCATE traits_chars;
INSERT INTO traits_chars (tid, cid, spoil)
- -- all char<->trait links of the latest revisions, including chars
- -- inherited from child traits if the parent trait was not mentioned
- -- directly.
+ -- all char<->trait links of the latest revisions, including chars inherited from child traits.
-- (also includes non-searchable traits, because they could have a searchable trait as parent)
- WITH RECURSIVE traits_chars_all(lvl, tid, cid, spoiler, searchable) AS (
- SELECT 15, tid, ct.id, spoil, true
- FROM chars_traits ct
- JOIN chars c ON c.id = ct.id
- WHERE NOT c.hidden
+ WITH RECURSIVE traits_chars_all(lvl, tid, cid, spoiler) AS (
+ SELECT 15, tid, ct.id, spoil
+ FROM chars_traits ct
+ WHERE id NOT IN(SELECT id from chars WHERE hidden)
UNION ALL
- SELECT lvl-1, tp.parent, tc.cid, tc.spoiler, t.searchable
+ SELECT lvl-1, tp.parent, tc.cid, tc.spoiler
FROM traits_chars_all tc
JOIN traits_parents tp ON tp.trait = tc.tid
JOIN traits t ON t.id = tp.parent
WHERE t.state = 2
AND tc.lvl > 0
- AND NOT EXISTS(SELECT 1 FROM chars_traits cti WHERE cti.tid = tp.parent AND cti.id = tc.cid)
)
- -- now grouped by (tid, cid) and with non-searchable traits filtered out
- SELECT tid, cid, (CASE WHEN AVG(spoiler) > 1.3 THEN 2 WHEN AVG(spoiler) > 0.7 THEN 1 ELSE 0 END)::smallint AS spoiler
- FROM traits_chars_all
- WHERE searchable
- GROUP BY tid, cid;
+ -- now grouped by (tid, cid), with non-searchable traits filtered out
+ SELECT tid, cid
+ , (CASE WHEN MIN(spoiler) > 1.3 THEN 2 WHEN MIN(spoiler) > 0.7 THEN 1 ELSE 0 END)::smallint AS spoiler
+ FROM traits_chars_all
+ WHERE tid IN(SELECT id FROM traits WHERE searchable)
+ GROUP BY tid, cid;
+ -- recreate index
+ CREATE INDEX traits_chars_tid ON traits_chars (tid);
-- and update the VN count in the tags table
UPDATE traits SET c_items = (SELECT COUNT(*) FROM traits_chars WHERE tid = id);
RETURN;
END;
-$$ LANGUAGE plpgsql;
+$$ LANGUAGE plpgsql SECURITY DEFINER;
-- Fully recalculate all rows in stats_cache