Функция book_name (сокращение авторов)

Напишем более универсальную функцию с дополнительным параметром - максимальное число авторов в названии.

Поскольку функция меняет сигнатуру (число и/или типы входных параметров), ее необходимо сначала удалить, а потом создать заново. В данном случае у функции есть зависимый объект - представление catalog_v, в котором она используется. Представление тоже придется пересоздать (в реальной работе все эти действия надо выполнять в одной транзакции, чтобы изменения вступили в силу атомарно).

=> DROP FUNCTION book_name(integer,text) CASCADE;
NOTICE:  drop cascades to view catalog_v
DROP FUNCTION
=> CREATE OR REPLACE FUNCTION book_name(book_id integer, title text, maxauthors integer DEFAULT 2)
RETURNS text
AS $$
DECLARE
    r record;
    res text;
BEGIN
    res := shorten(title) || '. ';
    FOR r IN (
        SELECT a.last_name, a.first_name, a.middle_name, ash.seq_num
        FROM   authors a
               JOIN authorship ash ON a.author_id = ash.author_id
        WHERE  ash.book_id = book_name.book_id
        ORDER BY ash.seq_num
    )
    LOOP
        EXIT WHEN r.seq_num > maxauthors;
        res := res || author_name(r.last_name, r.first_name, r.middle_name) || ', ';
    END LOOP;
    res := rtrim(res, ', ');
    IF r.seq_num > maxauthors THEN
        res := res || ' и др.';
    END IF;
    RETURN res;
END;
$$ STABLE LANGUAGE plpgsql;
CREATE FUNCTION
=> CREATE OR REPLACE VIEW catalog_v AS
SELECT b.book_id,
       b.title,
       b.onhand_qty,
       book_name(b.book_id, b.title) AS display_name,
       b.authors
FROM   books b
ORDER BY display_name;
CREATE VIEW
=> SELECT book_id, display_name FROM catalog_v;
 book_id |                     display_name                      
---------+-------------------------------------------------------
       4 | Война и мир. Толстой Л. Н.
       2 | Муму. Тургенев И. С.
       5 | Путешествия в некоторые удаленные страны.... Свифт Д.
       1 | Сказка о царе Салтане. Пушкин А. С.
       3 | Трудно быть богом. Стругацкий А. Н., Стругацкий Б. Н.
       6 | Хрестоматия. Пушкин А. С., Толстой Л. Н. и др.
(6 rows)

Вариант на чистом SQL для сравнения:

=> CREATE OR REPLACE FUNCTION book_name(book_id integer, title text, maxauthors integer DEFAULT 2)
RETURNS text
AS $$
SELECT shorten(book_name.title)
       || '. '
       || string_agg(author_name(a.last_name, a.first_name, a.middle_name),
                     ', ' ORDER BY ash.seq_num)
          FILTER (WHERE ash.seq_num <= maxauthors)
       || CASE
              WHEN max(ash.seq_num) > maxauthors THEN ' и др.'
              ELSE ''
          END
FROM   authors a
       JOIN authorship ash ON a.author_id = ash.author_id
WHERE  ash.book_id = book_name.book_id;
$$ STABLE LANGUAGE sql;
CREATE FUNCTION
=> SELECT book_id, display_name FROM catalog_v;
 book_id |                     display_name                      
---------+-------------------------------------------------------
       4 | Война и мир. Толстой Л. Н.
       2 | Муму. Тургенев И. С.
       5 | Путешествия в некоторые удаленные страны.... Свифт Д.
       1 | Сказка о царе Салтане. Пушкин А. С.
       3 | Трудно быть богом. Стругацкий А. Н., Стругацкий Б. Н.
       6 | Хрестоматия. Пушкин А. С., Толстой Л. Н. и др.
(6 rows)