Functions written in PL/pgSQL
or SQL
can be defined as RETURNS void
. I recently stumbled upon an odd difference in the result.
Consider the following demo:
CREATE OR REPLACE FUNCTION f_sql()
RETURNS void
LANGUAGE sql AS
'SELECT NULL::void'; -- = "do nothing", no special meaning
CREATE OR REPLACE FUNCTION f_plpgsql()
RETURNS void
LANGUAGE plpgsql AS
$func$
BEGIN
NULL; -- = "do nothing", no special meaning
END;
$func$;
The function f_sql()
uses the only possible way for a SELECT
(as last command) in a SQL function that RETURNS void
. I use it just because it is the simplest way for the purposes of this test - any other function, with UPDATE
or DELETE
for instance, shows the same behavior.
Now, void
is a fictive type. While the plpgsql
function seems to return the equivalent of an empty string as type void
- effectively ''::void
. The sql
function seems to return 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
This can have subtle and confusing side effects.
What is the reason behind the difference?