CREATE OR REPLACE FUNCTION getParentLtree(parent_id bigint, tbl_name varchar)
RETURNS ltree AS
$BODY$
DECLARE
parent_ltree ltree;
BEGIN
-- This works fine:
-- select into parent_ltree l_tree from tbl1 where id = parent_id;
EXECUTE format('select into parent_ltree l_tree from %I
where id = %I', tbl_name,parent_id);
RETURN parent_ltree;
END;
$BODY$ LANGUAGE plpgsql;
There are 2 issues in above function:
parent_id
is integer
but it is replaced with quotes? What is the correct format specifier for int
variables?select into
does not work with EXECUTE
? How can I make above commented query to use table name passed?This would be shorter, faster and safer:
CREATE OR REPLACE FUNCTION get_parent_ltree(parent_id bigint, tbl_name regclass
, OUT parent_ltree ltree) AS
$func$
BEGIN
EXECUTE format('SELECT l_tree FROM %s WHERE id = $1', tbl_name)
INTO parent_ltree
USING parent_id;
END
$func$ LANGUAGE plpgsql;
Most importantly, use the USING
clause of EXECUTE
for parameter values. Don't convert them to text
, concatenate and interpret them back. That would be slower and error-prone.
Normally you would use the %I
specifier with format()
for identifiers like the table name. There is an even better way, though: use a regclass
object-identifier type. Details here:
Table name as a PostgreSQL function parameter
Use an OUT
parameter to simplify your code. Performance is the same.
Don't use unquoted CaMeL case identifiers like getParentLtree
in Postgres. Details in the manual.