I am pretty new to postgres & especially new to ltree. Searching the web for ltree brought me to examples where the tree was build by chaining characters. But I want to use the primary key & foreign key.
Therefore I build the following table:
create table fragment(
id serial primary key,
description text,
path ltree
);
create index tree_path_idx on fragment using gist (path);
Instead of A.B.G I want to have 1.3.5. A root in the examples online is added like so:
insert into fragment (description, path) values ('A', 'A');
Instead of A I want to have the primary key (which I don't know at that moment). Is there a way to do that?
When adding a child I got the same problem:
insert into tree (letter, path) values ('B', '0.??');
I know the id of the parent but not of the child that I want to append.
Is there a way to do that or am I completey off track?
Thank you very much!
You could create a trigger which modifies path
before each insert. For example, using this setup:
DROP TABLE IF EXISTS fragment;
CREATE TABLE fragment(
id serial primary key
, description text
, path ltree
);
CREATE INDEX tree_path_idx ON fragment USING gist (path);
Define the trigger:
CREATE OR REPLACE FUNCTION before_insert_on_fragment()
RETURNS TRIGGER LANGUAGE plpgsql AS $$
BEGIN
new.path := new.path || new.id::text;
return new;
END $$;
DROP TRIGGER IF EXISTS before_insert_on_fragment ON fragment;
CREATE TRIGGER before_insert_on_fragment
BEFORE INSERT ON fragment
FOR EACH ROW EXECUTE PROCEDURE before_insert_on_fragment();
Test the trigger:
INSERT INTO fragment (description, path) VALUES ('A', '');
SELECT * FROM fragment;
-- | id | description | path |
-- |----+-------------+------|
-- | 1 | A | 1 |
Now insert B under id = 1:
INSERT INTO fragment (description, path) VALUES ('B', (SELECT path FROM fragment WHERE id=1));
SELECT * FROM fragment;
-- | id | description | path |
-- |----+-------------+------|
-- | 1 | A | 1 |
-- | 2 | B | 1.2 |
Insert C under B:
INSERT INTO fragment (description, path) VALUES ('C', (SELECT path FROM fragment WHERE description='B'));
SELECT * FROM fragment;
-- | id | description | path |
-- |----+-------------+-------|
-- | 1 | A | 1 |
-- | 2 | B | 1.2 |
-- | 3 | C | 1.2.3 |