I'm using Postgraphile, which has you create functions that take row sets as arguments. For instance, I have a function that takes a system_versions
row set as a parameter:
CREATE OR REPLACE FUNCTION public.system_versions_edition_versions(
system_version system_versions,
system_title character varying DEFAULT NULL::character varying
)
RETURNS SETOF edition_versions
LANGUAGE sql
STABLE STRICT SECURITY DEFINER
AS $function$
SELECT ev.*
FROM public.edition_versions ev
INNER JOIN public.editions e ON ev.edition_id = e.id
INNER JOIN public.systems s ON e.system_id = s.id
INNER JOIN public.system_versions sv ON s.id = sv.system_id
WHERE sv.id = system_version.id
AND (
system_title IS NULL
OR
sv.title = system_title
)
;
$function$
;
Normally these functions are called by Postgraphile, but I need to call this one manually for testing ... and I can't figure out how to provide the parameter.
When I try:
SELECT public.system_versions_edition_versions(public.system_versions);
I get:
ERROR: missing FROM-clause entry for table "public"
LINE 1: select public.system_versions_edition_versions(public.system...
But when I try to SELECT the table ...
SELECT public.system_versions_edition_versions(SELECT * FROM public.
system_versions);
I get:
ERROR: syntax error at or near "select"
LINE 1: select public.system_versions_edition_versions(select * from...
When I have a function with a "row set" parameter, can anyone explain how I provide that parameter?
It looks like system_version
argument type is row rather than rowset. Otherwise sv.id = system_version.id
would cause an error. Since public.system_versions
is a table then system_versions
is its row type, like system_versions%rowtype
in PL/pgSQL.
You can call it using a scalar subquery like this:
SELECT public.system_versions_edition_versions(
(
SELECT t
FROM public.system_versions t
-- WHERE <your logic here>
LIMIT 1 -- a scalar subquery must return a single row
)
);
or
select public.system_versions_edition_versions(t)
from public.system_versions t
-- where <your logic here>;
You may also consider using a lateral join.