Question

I'm altering a PLPGSQL function and I'm having a small problem. First let me post it's declaration:

CREATE OR REPLACE FUNCTION permissions(_principal text)
  RETURNS SETOF record AS
$BODY$
DECLARE
    id integer := 0;
    rolerow record ;

In this function there are a few cases, controled by IF statements, and in all of them, the return is the UNION of more than 1 query, such as this:

FOR rolerow IN (
    (SELECT 'role1' AS role FROM table1 WHERE id = table1.id)
    UNION (SELECT 'role2' AS role FROM table2 WHERE id = table2.id)
    UNION (SELECT 'role3' AS role FROM table3 WHERE id = table3.id)
    ) 
LOOP
    RETURN NEXT rolerow;
END LOOP;
RETURN;

And it all works fine, but in one case, I need to return a single query result, that would be a SETOF record but with only 1 item, so I did it like this:

FOR rolerow IN (
    SELECT 'role4' AS role FROM table4 WHERE id = table4.id
) 
LOOP
    RETURN NEXT rolerow;
END LOOP;
RETURN;

I also tried

RETURN QUERY SELECT 'role4' AS role FROM table4 WHERE id = table4.id;

But in both cases I get the same error as a response:

ERROR:  structure of query does not match function result type
DETAIL:  Returned type unknown does not match expected type text in column 1.

Does anyone have any idea how I can fix this?

I'll provide extra information in case this isn't enough.

Était-ce utile?

La solution

You need an explicit cast for the string literal 'role4', which is not typed (type "unknown") unlike you seem to expect:

 SELECT 'role4'::text AS role FROM  ...

Generally, looping is more expensive for your simple examples. Use RETURN QUERY like you already tested.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top