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.

Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top