Статья основана на семнадцатом видео из 31 темы курса SQL 2.0 — PL/pgSQL в PostgreSQL от Аристова Евгения, который является логическим продолжением курса SQL c 0. Ссылки на видео на платформах RUTUBE и VK video.
В данной статье подробно разбираются полиморфные типы данных функций и ограничения при их использовании.
В прошлой статье разбираются перезагрузка функции, особенности реализации, сложности отладки и выбора.
Презентация и исходники доступны по ссылке.
Полиморфизм функций
Полиморфизм функций в PostgreSQL позволяет создавать функции, которые могут работать с разными типами данных. Это более гибкий подход по сравнению с перегрузкой, поскольку одна функция может обрабатывать множественные типы данных.
Полиморфные типы данных
- anyelement — любой тип данных
- anyarray — любой массив
- anynonarray — любой не-массивный тип
- anyenum — любой enum тип
- anyrange — любой диапазонный тип
Например:
CREATE FUNCTION maximum(a anyelement, b anyelement) RETURNS anyelement AS $$
SELECT CASE WHEN a > b THEN a ELSE b END;
$$ LANGUAGE SQL;
SELECT maximum(1,2);
Главное, чтобы над таким типов данных при вызове работал оператор (<>= и т.д.)
Ограничения
Ограничение: нельзя использовать anyelement в RETURNS TABLE:
НЕ РАБОТАЕТ:
CREATE OR REPLACE FUNCTION get_polymorphic_table()
RETURNS TABLE(id anyelement, name text) AS $$ ... $$;
РЕШЕНИЕ: использовать OUT параметры — но помним разницу:
CREATE OR REPLACE FUNCTION get_polymorphic_data(in i anyelement, OUT id anyelement, OUT data jsonb)
RETURNS SETOF record AS $$ – возврат анонимного множества
обязательно должен быть задан 1 IN эниэлемент параметр!
Мощный инструмент для:
- Создания универсальных утилит
- Уменьшения дублирования кода
- Повышения гибкости API
Основные преимущества:
- Одна функция для многих типов
- Автоматическое определение типов
- Сокращение количества функций
Ограничения:
- Сложность отладки
- Ограниченная поддержка в некоторых контекстах
- Возможные проблемы с производительностью
Пример кода:
CREATE OR REPLACE FUNCTION get_type_info(value anyelement)
RETURNS TABLE(type_name text, type_oid oid) AS $$
BEGIN
SELECT
pg_typeof(value)::text,
pg_typeof(value)::oid
INTO type_name, type_oid;
RETURN NEXT;
END;
$$ LANGUAGE plpgsql;
Больше примеров доступно на гитхабе и в видео.
В следующей статье мы разберём процедуры.
Добавить комментарий