Функции, написанные в PL/pgSQL или SQL, могут быть определены как RETURNS void. Недавно я наткнулся на странную разницу в результатах.
Рассмотрим следующую демонстрацию:
CREATE OR REPLACE FUNCTION f_sql()
RETURNS void AS
'SELECT NULL::void' -- "do nothing", no special meaning
LANGUAGE sql;
CREATE OR REPLACE FUNCTION f_plpgsql()
RETURNS void AS
$$
BEGIN
NULL; -- "do nothing", no special meaning
END;
$$ LANGUAGE plpgsql;
Функция f_sql() использует единственный возможный способ для SELECT (как последняя команда) в функции SQL, которая RETURNS void. Я использую его только потому, что это самый простой способ для целей этого теста. Например, любая другая функция с UPDATE или DELETE показывает то же поведение.
Теперь void является фиктивным типом. Пока функция plpgsql возвращает эквивалент пустой строки как type void, эффективно ''::void. Кажется, что функция SQL возвращает NULL::void.
db=# SELECT f_sql() IS NULL;
?column?
----------
t
db=# SELECT f_sql()::text IS NULL;
?column?
----------
t
db=# SELECT f_plpgsql() IS NULL;
?column?
----------
f
db=# SELECT f_plpgsql()::text = '';
?column?
----------
t
Это может иметь тонкие и запутывающие побочные эффекты.
В чем причина разницы?