Question

I'm newbie in plpgsql. What is wrong in my function declaration?

It's rises the error:

ERROR:  syntax error at or near "array_append". LINE 19:
array_append(parent.childs , get_childs( ROW( child.id_pk, c...  ***

The function:

CREATE TYPE category_return AS (
    id_pk INT,
    parent_id_fk INT,
    name varchar,
    path ltree,
    childs json[]
);

------------------------

CREATE OR REPLACE FUNCTION get_childs ( parent category_return )

RETURNS category_return AS
$BODY$

DECLARE
    child record;
BEGIN
FOR child IN 
    SELECT * FROM categories c WHERE c.parent_id_fk = parent.id_pk 
LOOP
    array_append(parent.childs , get_childs( ROW( child.id_pk, child.parent_if_fk, child.name, child.path, '[]'::json[]) ) );
END LOOP

RETURN row_to_json(parent);

END;
$BODY$ LANGUAGE plpgsql;
Was it helpful?

Solution

The cause for the error at hand is that you would have to assign the result of the array_append() to a variable. Like:

some_var := array_append(parent.childs , get_childs( ... ));

But the whole function is twisted in various ways and still wouldn't work.

No mention of what you are trying to achieve, so here is an educated guess (updated with recursive version):

CREATE OR REPLACE FUNCTION get_children (_id_pk int)
  RETURNS TABLE (id_pk int, parent_if_fk int, name text, path int[]) AS
$func$
WITH RECURSIVE cte AS (
    SELECT c.id_pk, c.parent_if_fk, c.name, ARRAY[c.id_pk] AS path
    FROM   categories c
    WHERE  c.parent_if_fk = $1

    UNION ALL
    SELECT c.id_pk, c.parent_if_fk, c.name, cte.path || c.id_pk
    FROM   cte
    JOIN   categories c ON c.parent_if_fk = c.id_pk 
    )
SELECT *
FROM   cte
ORDER  BY path
$func$ LANGUAGE sql;

Returns all rows in the hierarchy below the starting ID.
Use a recursive CTE in a plain SQL function. No plpgsql necessary.

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