Re: Trees: maintaining pathnames - Mailing list pgsql-sql

From Dan Langille
Subject Re: Trees: maintaining pathnames
Date
Msg-id 3DD8B3BA.13415.AE7BF648@localhost
Whole thread Raw
In response to Re: Trees: maintaining pathnames  (greg@turnstep.com)
List pgsql-sql
On 18 Nov 2002 at 1:09, greg@turnstep.com wrote:

> 
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> NotDashEscaped: You need GnuPG to verify this message
> 
> 
> Instead of storing the path in each row, why not let Postgres 
> take care of computing it with a function? Then make a view 
> and you've got the same table, without all the triggers.

This is how it is now done.  I wanted to be able to so this fairly 
quickly:
  select * from tree where pathname like '/usr/local/%'

in order to get the subtree below a given point.  Sorry I didn't 
mention that before.

> 
> CREATE TABLE tree (
>  id        INTEGER NOT NULL,
>  parent_id INTEGER,
>  "name"    TEXT NOT NULL,
>  PRIMARY KEY (id)
> );
> 
> 
> INSERT INTO tree VALUES (1,NULL,'');
> INSERT INTO tree VALUES (2,1,'usr');
> INSERT INTO tree VALUES (3,1,'tmp');
> INSERT INTO tree VALUES (4,1,'home');
> INSERT INTO tree VALUES (5,4,'greg');
> INSERT INTO tree VALUES (6,5,'etc');
> 
> CREATE OR REPLACE FUNCTION pathname(INTEGER)
> RETURNS TEXT AS
> '
> 
> DECLARE 
>   mypath TEXT;
>   myname TEXT;
>   myid   INTEGER;
> 
> BEGIN
> 
>   SELECT parent_id,name FROM tree WHERE id=$1 INTO myid,mypath;
>   IF mypath IS NULL THEN
>     RETURN ''No such id\n'';
>   END IF;
> 
>   LOOP
>     SELECT parent_id,name FROM tree WHERE id=myid INTO myid,myname;
>     mypath := ''/'' || mypath;
>     EXIT WHEN myid IS NULL;
>     mypath := myname || mypath;
>   END LOOP;
> 
> RETURN mypath;
> 
> END;
> ' LANGUAGE 'plpgsql';
> 
> CREATE VIEW mytree AS SELECT *, PATHNAME(id) AS path FROM tree;
> 
> SELECT * FROM tree ORDER BY id;
> 
>  id | parent_id | name 
> ----+-----------+------
>   1 |           | 
>   2 |         1 | usr
>   3 |         1 | tmp
>   4 |         1 | home
>   5 |         4 | greg
>   6 |         5 | etc
> (6 rows)
> 
> SELECT * FROM mytree ORDER BY id;
> 
>  id | parent_id | name |      path      
> ----+-----------+------+----------------
>   1 |           |      | /
>   2 |         1 | usr  | /usr
>   3 |         1 | tmp  | /tmp
>   4 |         1 | home | /home
>   5 |         4 | greg | /home/greg
>   6 |         5 | etc  | /home/greg/etc
> (6 rows)
> 
> UPDATE tree SET name='users' WHERE id=4;
> 
> SELECT * FROM mytree ORDER BY id;
> 
>  id | parent_id | name  |      path       
> ----+-----------+-------+-----------------
>   1 |           |       | /
>   2 |         1 | usr   | /usr
>   3 |         1 | tmp   | /tmp
>   4 |         1 | users | /users
>   5 |         4 | greg  | /users/greg
>   6 |         5 | etc   | /users/greg/etc
> (6 rows)

That's good.  Thank you.
-- 
Dan Langille : http://www.langille.org/



pgsql-sql by date:

Previous
From: Oliver Elphick
Date:
Subject: Re: Problems invoking psql. Help please.
Next
From: Hugh Esco
Date:
Subject: Re: Problems invoking psql. Help please.