Напишем более универсальную функцию: это не потребует усложнения кода, и позволит обойтись без "магических констант".
=> CREATE OR REPLACE FUNCTION shorten(s text, max_len integer DEFAULT 45, suffix text DEFAULT '...') RETURNS text AS $$ DECLARE suffix_len integer := length(suffix); BEGIN RETURN CASE WHEN length(s) > max_len THEN left(s, max_len - suffix_len) || suffix ELSE s END; END; $$ IMMUTABLE LANGUAGE plpgsql;
CREATE FUNCTION
Проверим:
=> SELECT shorten('Путешествия в некоторые удаленные страны мира в четырех частях: сочинение Лемюэля Гулливера, сначала хирурга, а затем капитана нескольких кораблей');
shorten ----------------------------------------------- Путешествия в некоторые удаленные страны м... (1 row)
=> SELECT shorten('Путешествия в некоторые удаленные страны мира в четырех частях: сочинение Лемюэля Гулливера, сначала хирурга, а затем капитана нескольких кораблей', 30);
shorten -------------------------------- Путешествия в некоторые уда... (1 row)
=> CREATE OR REPLACE FUNCTION book_name(book_id integer, title text) RETURNS text AS $$ SELECT shorten(title) || '. ' || string_agg(author_name(a.last_name, a.first_name, a.middle_name), ', ' ORDER BY ash.seq_num) 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
=> CREATE OR REPLACE FUNCTION shorten(s text, max_len integer DEFAULT 45, suffix text DEFAULT '...') RETURNS text AS $$ DECLARE suffix_len integer := length(suffix); short text := suffix; pos integer; BEGIN IF length(s) < max_len THEN RETURN s; END IF; FOR pos in 1 ..least(max_len-suffix_len+1, length(s)) LOOP IF substr(s,pos-1,1) != ' ' AND substr(s,pos,1) = ' ' THEN short := left(s, pos-1) || suffix; END IF; END LOOP; RETURN short; END; $$ IMMUTABLE LANGUAGE plpgsql;
CREATE FUNCTION
Проверим:
=> SELECT shorten('Путешествия в некоторые удаленные страны мира в четырех частях: сочинение Лемюэля Гулливера, сначала хирурга, а затем капитана нескольких кораблей');
shorten --------------------------------------------- Путешествия в некоторые удаленные страны... (1 row)
=> SELECT shorten('Путешествия в некоторые удаленные страны мира в четырех частях: сочинение Лемюэля Гулливера, сначала хирурга, а затем капитана нескольких кораблей', 30);
shorten ---------------------------- Путешествия в некоторые... (1 row)