Функции, написанные в 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
Это может иметь тонкие и запутывающие побочные эффекты.
В чем причина разницы?