I am using PostgreSQL 9.5.4 and trying to create a lambda function based on this code: https://github.com/decibel/pg_lambda/blob/master/sql/lambda.sql
set client_min_messages to debug;
create or replace function lambda_record(
code text,
variadic inputs anyarray
) returns record language plpgsql as $code$
declare
fname text;
foid regprocedure;
fargs regtype[];
call_args text[];
sql text;
out record;
begin
-- name of function
fname := format('pg_temp.lambda_function_%s', md5(code));
raise debug 'fname=%', fname;
-- create function
sql := format('create function %s%s', fname, code);
raise debug 'sql=%', sql;
execute sql;
-- get function id and arguments
foid := fname::regproc::oid;
select proargtypes::regtype[] into fargs
from pg_proc where oid = foid;
call_args := array(
select format('%L::%s', input, argtype)
from unnest(inputs, fargs) as u(input, argtype)
);
sql := format(
'select %s(%s)',
foid::oid::regproc,
array_to_string(call_args, ', ')
);
raise debug 'sql=%', sql;
-- out is a string but should be type record
execute sql into out using inputs;
raise debug 'out=%', out;
-- drop function
sql := format('drop function %s', foid::text);
raise debug 'sql=%', sql;
execute sql;
return out;
end;
$code$;
select lambda_record(
$lambda$(
IN arg1 numeric,
IN arg2 numeric,
OUT out1 numeric,
OUT out2 numeric
) returns record language sql AS $$
select $1::numeric, $2::numeric;
$$
$lambda$, 1, 2);
The problem is that the out
variable in lambda_record()
returns a string instead of a record:
SET
Time: 0.539 ms
psql:/Users/ian/Desktop/lambda3.sql:55: LOG: duration: 2.759 ms
CREATE FUNCTION
Time: 3.445 ms
psql:/Users/ian/Desktop/lambda3.sql:64: DEBUG: fname=pg_temp.lambda_function_f1ee9780eb612939b06081fce4ba88cb
psql:/Users/ian/Desktop/lambda3.sql:64: DEBUG: sql=create function pg_temp.lambda_function_f1ee9780eb612939b06081fce4ba88cb(
IN arg1 numeric,
IN arg2 numeric
) returns record language sql AS $$
select $1::numeric, $2::numeric;
$$
psql:/Users/ian/Desktop/lambda3.sql:64: DEBUG: sql=select pg_temp_2.lambda_function_f1ee9780eb612939b06081fce4ba88cb('1'::numeric, '2'::numeric)
psql:/Users/ian/Desktop/lambda3.sql:64: DEBUG: out=("(1,2)")
psql:/Users/ian/Desktop/lambda3.sql:64: DEBUG: sql=drop function pg_temp_2.lambda_function_f1ee9780eb612939b06081fce4ba88cb(numeric,numeric)
psql:/Users/ian/Desktop/lambda3.sql:64: LOG: duration: 7.511 ms
┌───────────────┐
│ lambda_record │
├───────────────┤
│ ("(1,2)") │
└───────────────┘
(1 row)
Time: 7.625 ms
psql:/Users/ian/Desktop/lambda3.sql:69: LOG: duration: 0.407 ms
For some reason the line execute sql into out using inputs
sets out to a RECORD
which contains a single value which is a TEXT
representation of what it should be.
But it should work like this:
create or replace function pg_temp.test(in arg1 integer, in arg2 integer,
out out1 integer, out out2 integer)
language sql as $$
select $1, $2;
$$;
select pg_temp.test(1, 2);
CREATE FUNCTION
Time: 0.529 ms
psql:/Users/ian/Desktop/lambda3.sql:70: LOG: duration: 0.193 ms
┌───────┐
│ test │
├───────┤
│ (1,2) │
└───────┘
(1 row)
I've been using Postgres for a long time, but I'm relatively new to the PL/pgsql language so any would be very appreciated.