From: | Joe Conway <mail(at)joeconway(dot)com> |
---|---|
To: | PostgreSQL Patches <pgsql-patches(at)postgresql(dot)org> |
Subject: | contrib/tablefunc update |
Date: | 2002-08-31 20:33:12 |
Message-ID: | 3D712808.6030500@joeconway.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-patches |
Attached is an update to contrib/tablefunc. It introduces a new
function, connectby(), which can serve as a reference implementation for
the changes made in the last few days -- namely the ability of a
function to return an entire tuplestore, and the ability of a function
to make use of the query provided "expected" tuple description.
Description:
connectby(text relname, text keyid_fld, text parent_keyid_fld,
text start_with, int max_depth [, text branch_delim])
- returns keyid, parent_keyid, level, and an optional branch string
- requires anonymous composite type syntax in the FROM clause. See
the instructions in the documentation below.
Example usage:
CREATE TABLE connectby_tree(keyid text, parent_keyid text);
INSERT INTO connectby_tree VALUES('row1',NULL);
INSERT INTO connectby_tree VALUES('row2','row1');
INSERT INTO connectby_tree VALUES('row3','row1');
INSERT INTO connectby_tree VALUES('row4','row2');
INSERT INTO connectby_tree VALUES('row5','row2');
INSERT INTO connectby_tree VALUES('row6','row4');
INSERT INTO connectby_tree VALUES('row7','row3');
INSERT INTO connectby_tree VALUES('row8','row6');
INSERT INTO connectby_tree VALUES('row9','row5');
-- with branch
SELECT * FROM
connectby('connectby_tree','keyid','parent_keyid','row2',0,'~')
AS t(keyid text, parent_keyid text, level int, branch text);
keyid | parent_keyid | level | branch
-------+--------------+-------+---------------------
row2 | | 0 | row2
row4 | row2 | 1 | row2~row4
row6 | row4 | 2 | row2~row4~row6
row8 | row6 | 3 | row2~row4~row6~row8
row5 | row2 | 1 | row2~row5
row9 | row5 | 2 | row2~row5~row9
(6 rows)
-- without branch
SELECT * FROM
connectby('connectby_tree','keyid','parent_keyid','row2', 0)
AS t(keyid text, parent_keyid text, level int);
keyid | parent_keyid | level
-------+--------------+-------
row2 | | 0
row4 | row2 | 1
row6 | row4 | 2
row8 | row6 | 3
row5 | row2 | 1
row9 | row5 | 2
(6 rows)
SELECT * FROM
connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 1, '~')
AS t(keyid text, parent_keyid text, level int, branch text);
keyid | parent_keyid | level | branch
-------+--------------+-------+-----------
row2 | | 0 | row2
row4 | row2 | 1 | row2~row4
row5 | row2 | 1 | row2~row5
(3 rows)
Notes:
1. keyid and parent_keyid must be the same data type
2. The column definition *must* include a third column of type INT4
for the level value output
3. If the branch field is not desired, omit both the branch_delim
input parameter *and* the branch field in the query column
definition
4. If the branch field is desired, it must be the forth column in the
query column definition, and it must be type TEXT
Seems to work pretty well. I have a "bill of material" (BOM) table with
about 220000 rows of part relationship data for assemblies (this is old,
but real, data from where I work). Starting with one top level assembly
(i.e. a system that we ship) the function builds a full BOM "explosion"
with about 3500 parts in 1.1 seconds. YMMV.
If there are no objections, please commit.
Thanks,
Joe
Attachment | Content-Type | Size |
---|---|---|
tablefunc-connectby.1.patch | text/plain | 24.4 KB |
From | Date | Subject | |
---|---|---|---|
Next Message | Joe Conway | 2002-08-31 23:26:01 | pg_settings doc patch |
Previous Message | Serguei Mokhov | 2002-08-31 20:17:04 | pg_resetxlog: Russian NLS |