66 lines
2.3 KiB
PL/PgSQL
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;
|