X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [200.46.204.2]) by svr1.postgresql.org (Postfix) with ESMTP id 79A40D1B582 for ; Mon, 17 Nov 2003 05:50:03 +0000 (GMT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (neptune.hub.org [200.46.204.2]) (amavisd-new, port 10024) with ESMTP id 93457-09 for ; Mon, 17 Nov 2003 01:49:33 -0400 (AST) Received: from news.hub.org (news.hub.org [200.46.204.72]) by svr1.postgresql.org (Postfix) with ESMTP id D3985D1B53A for ; Mon, 17 Nov 2003 01:49:32 -0400 (AST) Received: from news.hub.org (news.hub.org [200.46.204.72]) by news.hub.org (8.12.9/8.12.9) with ESMTP id hAH5nWNu032538 for ; Mon, 17 Nov 2003 05:49:32 GMT (envelope-from news@news.hub.org) Received: (from news@localhost) by news.hub.org (8.12.9/8.12.9/Submit) id hAH5lSFx032402 for pgsql-sql@postgresql.org; Mon, 17 Nov 2003 05:47:28 GMT From: "Randolf Richardson, DevNet SysOp 29" X-Newsgroups: comp.databases.postgresql.sql Subject: Re: SOLVED: Emulating 'connect by prior' using stored proc Date: Mon, 17 Nov 2003 05:47:28 +0000 (UTC) Organization: Inter-Corporate Computer & Network Services, Inc. Lines: 64 Message-ID: References: X-Complaints-To: usenet@news.hub.org User-Agent: Xnews/5.04.25 X-Face: +kXh]8'{:R`HzXla-aT~$s8a+C)k/B%RBr$_3sP`[kA}cl7#mD^9Z:oM`HpoC_kUEH['RZ*Ob%pz\ww^q&x)~zc`.xd]VQ4WN/3t2nS-BvI%LF\B4:\9$EI:/|<)`?8I_; xzG@SOYFir/gk_eB4"Rl43-h%)8O0sR$b&Mp3XHR(0j= X-Face-Author: Randolf Richardson (composed with Adobe Photoshop) To: pgsql-sql@postgresql.org X-Virus-Scanned: by amavisd-new at postgresql.org X-Archive-Number: 200311/223 X-Sequence-Number: 16038 [sNip] > In order to make this work with postgres an additional table is needed > that can hold the level (depth) of the branch because pgsql doesn't like > returning a tuple that isn't based on a defined structure. Once you've > created this table you can pretty much forget about it. > > CREATE TABLE "node_relationships_n_level" ( > "level" integer > ) inherits (node_relationships); > > > Now create your stored procedure. > > CREATE OR REPLACE FUNCTION "crawl_tree" (integer,integer) RETURNS SETOF > node_relationships_n_level AS 'DECLARE > temp RECORD; > child RECORD; > BEGIN > SELECT INTO temp *, $2 AS level FROM node_relationships WHERE > child_node_id = $1; > > IF FOUND THEN > RETURN NEXT temp; > FOR child IN SELECT child_node_id FROM node_relationships WHERE > parent_node_id = $1 ORDER BY ordinal LOOP > FOR temp IN SELECT * FROM crawl_tree(child.child_node_id, $2 + > 1) LOOP > RETURN NEXT temp; > END LOOP; > END LOOP; > END IF; > RETURN NULL; > END; > ' LANGUAGE 'plpgsql'; > > > The second parameter must be zero. This is a kludge because this is a > recursive function and I needed some way of passing the level to > successive function calls. However, if you like, you could consider this > to be a "level offset"--set it to '2' and all the levels returned will > be n + 2. > > Execute "SELECT * FROM crawl_tree(682904,0)" and you're done. > > Hope this helps people. I have one question because I'm not clear about something with your implementation (a good one too by the looks of it -- thanks for sharing this information); if I start my query from an item at level 5, will the level be reflected as such, or will it dynamically start at 1? As I understand it, in Oracle the level would begin at 1 in this case. Thanks in advance. -- Randolf Richardson - rr@8x.ca Inter-Corporate Computer & Network Services, Inc. Vancouver, British Columbia, Canada http://www.8x.ca/ This message originated from within a secure, reliable, high-performance network ... a Novell NetWare network.