This is my remote function:
CREATE OR REPLACE FUNCTION public._test1()
RETURNS record
LANGUAGE plpgsql
AS $function$
DECLARE
rec record;
BEGIN
select 1,2 into rec;
return rec;
END $function$;
This is my local function call:
SELECT x.a, x.b
FROM dblink('conn_str', 'select public._test1();')
as x(a int ,b int);
This is the error thrown:
ERROR: remote query result rowtype does not match the specified FROM clause rowtype
Since DBLINK requires that I define a schema to place the function's return items, how do I make the call to recognize a record
type being returned by the function?
Best Answer
To understand what's going on, first check what is being done on the remote:
This does return a record, not two integers. When the
dblink()
call reportsit's because locally you defined the row type as
x(a int, b int)
, but that doesn't match the record on the remote. The reason is thatdblink()
itself doesn't know about (as it itself has aSETOF record
return type), therefore it cannot push this information to the remote. So what you have to do is the following:Specifying the record type twice seems superfluous, but if you omitted the local one, it would result in another error:
Omitting the remote record definition:
(The difference in the error message shows this time the problem is on the remote side.)
One ore thing that is different in my version is
SELECT * FROM _test()
. See what happens when you call the function in theSELECT
list instead of theFROM
clause:You can make this nicer if you created the remote function as
RETURNS TABLE
(or, equivalently, defineOUT
arguments there):The
record
type is designed to be flexible, but it comes at a price. You cannot avoid paying this price withdblink()
, though, as it has to be able to accommodate any return type.