36.6. Перегрузка функций#

36.6. Перегрузка функций

36.6. Перегрузка функций

Более одной функции может быть определено с тем же SQL именем, при условии, что они принимают разные аргументы. Другими словами, имена функций могут быть перегружены. Независимо от того, используете ли вы это, эта возможность требует предосторожности при вызове функций в базах данных, где некоторые пользователи не доверяют другим пользователям; см. Раздел 10.3. При выполнении запроса сервер определит, какую функцию вызвать на основе типов данных и количества предоставленных аргументов. Перегрузка также может использоваться для имитации функций с переменным числом аргументов, до конечного максимального числа.

При создании семейства перегруженных функций следует быть осторожным, чтобы не создавать неоднозначности. Например, учитывая функции:

CREATE FUNCTION test(int, real) RETURNS ...
CREATE FUNCTION test(smallint, double precision) RETURNS ...

не сразу ясно, какая функция будет вызвана с таким простым вводом, как test(1, 1.5). В настоящее время реализованные правила разрешения описаны в Глава 10, но неразумно проектировать систему, которая тонко полагается на это поведение.

Функция, принимающая единственный аргумент составного типа, обычно не должна иметь того же имени, что и любой атрибут (поле) этого типа. Напомним, что attribute(table) считается эквивалентным table.attribute. В случае, когда возникает неоднозначность между функцией на составном типе и атрибутом составного типа, всегда будет использоваться атрибут. Возможно переопределить это выбор, указав схему для имени функции (то есть schema.function(table)), но лучше избежать проблемы, не выбирая конфликтующие имена.

Еще одна возможная конфликтная ситуация возникает между вариативными и невариативными функциями. Например, можно создать как foo(numeric), так и foo(VARIADIC numeric[]). В этом случае неясно, какая из них должна быть выбрана для вызова с одним числовым аргументом, например, foo(10.1). Правило состоит в том, что используется функция, которая появляется раньше в поисковом пути, или, если две функции находятся в одной схеме, предпочтение отдается невариативной функции.

При перегрузке функций на языке C существует дополнительное ограничение: имя C каждой функции в семействе перегруженных функций должно отличаться от имен C всех других функций, как внутренних, так и динамически загружаемых. Если это правило нарушается, поведение не является переносимым. Возможна ошибка связывателя времени выполнения или вызов одной из функций (обычно внутренней). Альтернативная форма AS для SQL-команды CREATE FUNCTION отделяет имя SQL-функции от имени функции в исходном коде на C. Например:

CREATE FUNCTION test(int) RETURNS int
    AS 'filename', 'test_1arg'
    LANGUAGE C;
CREATE FUNCTION test(int, int) RETURNS int
    AS 'filename', 'test_2arg'
    LANGUAGE C;

Имена функций на языке C здесь отражают одну из множества возможных конвенций.