yhdev/pub/download/code/vntitles2.sql
2023-01-08 16:11:09 +01:00

66 lines
2.3 KiB
PL/PgSQL

BEGIN;
CREATE TYPE langprefs AS (
t1_lang language, -- NULL for original language
t2_lang language,
t3_lang language,
t4_lang language,
t5_lang language,
t1_latin boolean,
t2_latin boolean,
t3_latin boolean,
t4_latin boolean,
t5_latin boolean,
t1_official boolean, -- always true for original language
t2_official boolean,
t3_official boolean,
t4_official boolean,
t5_official boolean
);
CREATE TYPE vntitle_state AS (
rank smallint,
title text
);
CREATE OR REPLACE FUNCTION vntitle_sfunc(state vntitle_state, t vn_titles, olang language, p langprefs) RETURNS vntitle_state AS $$
BEGIN
IF state.rank > 1 AND COALESCE(p.t1_lang, olang) = t.lang AND (NOT p.t1_official OR t.official) THEN
RETURN ROW(1::smallint, COALESCE(CASE WHEN p.t1_latin THEN t.latin ELSE NULL END, t.title));
ELSIF state.rank > 2 AND COALESCE(p.t2_lang, olang) = t.lang AND (NOT p.t2_official OR t.official) THEN
RETURN ROW(2::smallint, COALESCE(CASE WHEN p.t2_latin THEN t.latin ELSE NULL END, t.title));
ELSIF state.rank > 3 AND COALESCE(p.t3_lang, olang) = t.lang AND (NOT p.t3_official OR t.official) THEN
RETURN ROW(3::smallint, COALESCE(CASE WHEN p.t3_latin THEN t.latin ELSE NULL END, t.title));
ELSIF state.rank > 4 AND COALESCE(p.t4_lang, olang) = t.lang AND (NOT p.t4_official OR t.official) THEN
RETURN ROW(4::smallint, COALESCE(CASE WHEN p.t4_latin THEN t.latin ELSE NULL END, t.title));
ELSIF state.rank > 5 AND COALESCE(p.t5_lang, olang) = t.lang AND (NOT p.t5_official OR t.official) THEN
RETURN ROW(5::smallint, COALESCE(CASE WHEN p.t5_latin THEN t.latin ELSE NULL END, t.title));
END IF;
RETURN state;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
CREATE OR REPLACE AGGREGATE vntitle(vn_titles, language, langprefs) (
SFUNC = vntitle_sfunc,
STYPE = vntitle_state,
INITCOND = '(6,)'
);
SET max_parallel_workers_per_gather = 0;
EXPLAIN ANALYZE
SELECT v.id, vntitle(t, v.olang, '(en,,,,,f,f,f,f,f,f,f,f,f,f)'::langprefs) title
FROM vn v
JOIN vn_titles t ON t.id = v.id
WHERE NOT hidden --AND v.id < 'v10'
GROUP BY v.id
ORDER BY title LIMIT 100;
EXPLAIN ANALYZE
SELECT v.id, max(t.title) as title
FROM vn v
JOIN vn_titles t ON t.id = v.id
WHERE NOT hidden --AND v.id < 'v10'
GROUP BY v.id
ORDER BY title LIMIT 100;