There is a function that returns 3 parameters one of which is a composite type:
CREATE OR REPLACE FUNCTION f1(
p_text text,
OUT result_status_id smallint,
OUT result_status_msg text,
OUT result_my_type my_type
)
RETURNS record AS
$BODY$
--body here
$BODY$
LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER
COST 100
The composite type my_type looks like following:
CREATE TYPE my_type AS
(d_real real,
d_int1 integer,
d_int2 integer,
d_int3 integer,
d_int4 integer,
d_int5 integer,
d_int6 integer,
d_int7 integer,
d_int8 integer,
d_int9 integer,
d_int10 integer,
d_bool boolean,
d_date date,
d_text text
);
There is another function f2 that calls function f1 in its body:
CREATE OR REPLACE FUNCTION f2(
p_text text
)
RETURNS record AS
$BODY$
DECLARE
l_status_id smallint;
l_status_msg text;
l_my_type my_type;
BEGIN
--some logic here
--this statement fails
SELECT * FROM f1(p_text) 'x'
INTO l_status_id, l_status_msg, l_my_type;
--logic continues here
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER
COST 100;
The problem is that when executing sql with the function I receive the following error:
ERROR: "l_my_type" is not a scalar variable
How may one get a composite type object from another function?
You are violating the rules. The manual:
where target can be a record variable, a row variable, or a comma-separated list of simple variables and record/row fields.
A record or row variable cannot be part of multiple-item INTO list.
One way around this:
CREATE OR REPLACE FUNCTION f2(p_text text)
RETURNS record AS
$BODY$
DECLARE
r record;
l_status_id smallint;
l_status_msg text;
l_my_type my_type;
BEGIN
SELECT *
FROM f1(p_text) x -- don't single quote 'x'
INTO r;
l_status_id := r.result_status_id;
l_status_msg := r.result_status_msg;
l_my_type := r.result_my_type;
RETURN r; -- or whatever ..
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
There are more ways. Depends where you are going with this. I hardly ever return an anonymous record.
Composite types in tuples are one of those things which is supported partially and you run into odd issues (particularly with thins like storage but that's a story for another time). One way you could accomplish this is:
CREATE TYPE return_type_for_function AS (
result_status_id smallint,
result_status_msg text,
result_my_type my_type
);
CREATE FUNCTION myfunc(....) RETURNS return_type_for_function ....
This is the way I have always done it. This is a little more mature than using OUT variables.
Here's a trivial example:
or_examples=# create table rel_examples.tabletest (id int);
CREATE TABLE
or_examples=# create table comp_table_test (test rel_examples.tabletest);
CREATE TABLE
or_examples=# create function test(int) returns comp_table_test
immutable language sql as $$
select row(row($1))::comp_table_test; $$;
CREATE FUNCTION
or_examples=# select test(1);
test
---------
("(1)")
(1 row)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With