Полиморфизм функций

Статья основана на семнадцатом видео из 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;

Больше примеров доступно на гитхабе и в видео.

В следующей статье мы разберём процедуры.


Опубликовано

в

Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

5 + 20 =