Вы нашли корень проблемы самостоятельно.Если быть точным: схема функции pub
должна быть указана в любом месте в текущей search_path
, необязательно должна быть схемой «по умолчанию» или «текущей»(первый в списке).Связанный:
Таким образом, Postgres не нашел функцию.Postgres 11 не отличается от Postgres 10 в этом отношении.Однако есть несколько примечательных связанных событий.Вы упомянули:
База данных была перенесена из PostgreSQL 10 с резервным копированием / восстановлением.
Обратите внимание на это тонкое изменение, указанное в примечаниях к выпуску для Postgres 11 :
Учитывать синтаксическую форму при устранении неоднозначности функции по сравнению со ссылками на столбцы (Том Лейн)
Когда x
- это имя таблицы или составной столбец, PostgreSQL традиционно рассматривал синтаксические формы f(x)
и x.f
длябыть эквивалентным, позволяя использовать такие приемы, как написание функции, а затем использовать ее, как если бы это был столбец с вычислением по требованию.Однако, если обе интерпретации возможны, всегда выбиралась интерпретация столбца, что приводило к неожиданным результатам, если пользователь намеревался интерпретировать функцию.Теперь, если есть неоднозначность, выбирается интерпретация, соответствующая синтаксической форме.
Итак, , если был столбец fullname
в таблицеreps
, а также отображаемая функция pub.fullname(pub.reps)
, Postgres 10, даже с функциональной нотацией, все равно выбрал бы столбец :
SELECT fullname(r) FROM reps r; -- resolves to column if it exists, ignoring function
db <> fiddle здесь для Postgres 10
Postgres 11 (более разумно) выбирает функцию:
db <> fiddle здесь для Postgres 11
Postgres 12 (в настоящее время бета) в конечном итоге реализует истинно сгенерированные столбцы. Примечания к выпуску:
- Добавить поддержку сгенерированных столбцов (Peter Eisentraut)
Содержимое сгенерированных столбцов вычисляется из выражений (включая ссылки на другие столбцы в той же таблице), вместо того, чтобы быть заданными командами INSERT
или UPDATE
.
Только STORED
сгенерированные столбцы сделали его в этом выпуске, хоть.Вариант (более интересный IMO) VIRTUAL
был перенесен на более позднюю версию .Надеясь на Postgres 13.
Ваш стол может выглядеть так:
CREATE TABLE pub.reps (
reps_id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY
, fname text NOT NULL
, lname text NOT NULL
, fullname text GENERATED ALWAYS AS (fname || ' ' || lname) STORED
);
db <> скрипка здесь
Я объявил fname
и lname
столбцы NOT NULL
.Иначе, ваша простая конкатенация (fname || ' ' || lname
) является ловушкой.См .: