I'm trying to write a PL/pgSQL function in postgres that returns a boolean expression. Currently the code looks like this:
CREATE OR REPLACE FUNCTION is_visible_to(role integer, from_role integer)
RETURNS boolean
LANGUAGE SQL STABLE STRICT AS $$
RETURN $1 = $2 OR first_predicate($1, $2) OR second_predicate($2, $1);
$$;
The functions first_predicate and second_predicate exist and return booleans, but I'm not getting much help looking at them because they are defined with something like
SELECT COUNT(*) > 0 FROM ... WHERE ...
I am getting the following syntax error:
ERROR: syntax error at or near "RETURN"
LINE 4: RETURN $1 = $2 first_predicate($1, $2) OR second_predicate(...
^
So obviously I'm misunderstanding something rather fundamental here. I'm sort of new to the whole PL/pgSQL thing, so links to a good tutorial or two would also be appreciated.
The project I'm working on uses postgres exclusively, and already contains a lot of postgres specific code, so solutions don't have to be portable to other databases.
Edit: Fixed it myself with
CREATE FUNCTION is_visible_to (role integer, from_role integer)
RETURNS BOOLEAN AS '
DECLARE
role ALIAS FOR $1;
from_role ALIAS FOR $2;
BEGIN
RETURN (role = from_role) OR
first_predicate(from_role, role) OR
second_predicate(from_role, role)
END;
' LANGUAGE 'plpgsql';
Would still appreciate an answer that explains why the later works and the former (even with the language changed to plpgsql
as suggested by @a_horse_with_no_name) does not, or provides some useful tutorials.
CREATE OR REPLACE FUNCTION is_visible_to(role integer, from_role integer)
RETURNS boolean
LANGUAGE sql STABLE STRICT AS
$func$
SELECT $1 = $2 OR first_predicate($1, $2) OR second_predicate($2, $1);
$func$;
With SELECT
. There is no RETURN
in plain SQL. Details in the manual here.
Or with short "standard SQL" notation - which happens to use a RETURN
keyword (added with Postgres 14, years after your question):
CREATE OR REPLACE FUNCTION is_visible_to(role integer, from_role integer)
RETURNS boolean
LANGUAGE sql STABLE STRICT
RETURN $1 = $2 OR first_predicate($1, $2) OR second_predicate($2, $1);
See:
CREATE OR REPLACE FUNCTION is_visible_to(role integer, from_role integer)
RETURNS boolean
LANGUAGE plpgsql STABLE STRICT AS
$func$
BEGIN
RETURN $1 = $2 OR first_predicate($1, $2) OR second_predicate($2, $1);
END
$func$;
BEGIN
and END
are required for PL/pgSQL. Details in the manual here.
Don't use the outdated (and redundant here) ALIAS FOR
syntax. It's discouraged in the manual. You can reference parameter names directly. In SQL functions, too, since Postgres 9.2.