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;
