Ошибка PostgreSQL 42725: ambiguous_function — перегрузка функций
- Ошибка выполнения запроса
ERROR: function "." is not unique (SQLSTATE 42725) - Планировщик запросов не может выбрать подходящую функцию из-за нескольких сигнатур с неявным приведением аргументов (Type Coercion).
- Сбои в работе сервисов интеграции или расширений при вызове перегруженных процедур.
1. Поиск всех перегруженных версий функции в pg_proc
SELECT p.proname, n.nspname, pg_get_function_identity_arguments(p.oid) as args
FROM pg_proc p
JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE p.proname = 'calculate_tax';2. Явное приведение типов при вызове функции
Если существуют функции calculate_tax(numeric, int) и calculate_tax(float8, bigint), передача нетипизированного литерала вызовет 42725:
-- Ошибочный вызов (неоднозначность):
SELECT calculate_tax(100.50, 10);
-- Исправленный вызов с явным кастом типов:
SELECT calculate_tax(100.50::numeric, 10::integer);3. Удаление дублирующих или устаревших сигнатур
-- Удаление конкретной сигнатуры с точным указанием аргументов:
DROP FUNCTION IF EXISTS calculate_tax(double precision, bigint);4. Исправление конфликтов между схемами
Если одноименные функции объявлены в разных схемах, укажите имя схемы явно:
SELECT custom_schema.calculate_tax(100.50::numeric, 10::integer); Частые вопросы (FAQ)
Почему PostgreSQL допускает создание функций с одинаковым именем?
PostgreSQL поддерживает полиморфизм и перегрузку (Overloading) функций. Функции могут иметь одинаковое имя, если у них различаются типы, порядок или количество входных аргументов.
Как ядро PostgreSQL выбирает функцию при вызове?
Ядро сопоставляет типы фактических параметров. Если точного совпадения нет, выполняется попытка неявного приведения категорий типов (String, Numeric). Если находится более одной равнозначной сигнатуры, генерируется ошибка 42725.
Что означает тип ANYELEMENT в параметрах функции?
Это полиморфный псевдотип. Он позволяет функции принимать аргументы любого типа, при этом ядро автоматически проверяет соответствие типов возвращаемых значений во время вызова.
Как перегрузить оператор без ошибки неоднозначности?
Операторы привязаны к строгим типам левого и правого операнда (LEFTARG, RIGHTARG). Избегайте создания операторов для псевдотипов any/unknown.