Ваш l oop неправильный, вам нужно использовать FOREACH
до l oop через элементы массива :
CREATE OR REPLACE FUNCTION allRelevantTeas() RETURNS TABLE(tea_id INTEGER) AS $function$
DECLARE
stmt TEXT;
tea_drinker text;
countries_with_tea TEXT[] := array['england', 'turkey', 'india', 'japan', 'china'];
BEGIN
stmt := '';
FOREACH tea_drinker in array countries_with_tea LOOP
stmt := stmt || format($$(SELECT tea_id FROM %I)$$, tea_drinker);
IF tea_drinker <> 'china' THEN
stmt := stmt || $$ UNION $$;
END IF;
END LOOP;
RETURN query execute stmt;
END $function$
LANGUAGE plpgsql STABLE;
Вы не Для действительно необходим UNION, вы можете использовать return query
для возврата нескольких результатов:
CREATE OR REPLACE FUNCTION allrelevantteas()
RETURNS TABLE(tea_id INTEGER) AS $function$
DECLARE
stmt TEXT;
tea_drinker text;
countries_with_tea TEXT[] := array['england', 'turkey', 'india', 'japan', 'china'];
BEGIN
stmt := '';
FOREACH tea_drinker in array countries_with_tea LOOP
stmt := format($$(SELECT tea_id FROM %I)$$, tea_drinker);
return query execute stmt;
END LOOP;
END $function$
LANGUAGE plpgsql STABLE;
Онлайн пример
Если вам нужен этот журнал, может быть лучше использовать наследование таблиц или представление для создания одной таблицы, содержащей все остальные.