X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id 631853B5BFD for ; Thu, 16 Dec 2004 02:49:08 +0000 (GMT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 37310-03 for ; Thu, 16 Dec 2004 02:48:54 +0000 (GMT) Received: from rproxy.gmail.com (rproxy.gmail.com [64.233.170.193]) by svr1.postgresql.org (Postfix) with ESMTP id E76173AC457 for ; Thu, 16 Dec 2004 02:48:57 +0000 (GMT) Received: by rproxy.gmail.com with SMTP id a36so1552915rnf for ; Wed, 15 Dec 2004 18:48:57 -0800 (PST) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:reply-to:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:references; b=kNdeNpuAeEOBz8++CTtB/mUV0vBI9//wjLDVzLpPtgyBFZZqVMK9VbmdBOw6Gym615Ts0bxyN5Ginj72HFgqZ9CdWu6ZZgEkfoEgbwyZPiI4XwfvXd0Ruf1un41t5AHcbmRu2gtlCfTVY3cPOVeHJjqMVCdTh+HdMQ1b6nOV/1I= Received: by 10.38.163.80 with SMTP id l80mr360912rne; Wed, 15 Dec 2004 18:48:57 -0800 (PST) Received: by 10.38.126.16 with HTTP; Wed, 15 Dec 2004 18:48:57 -0800 (PST) Message-ID: Date: Wed, 15 Dec 2004 21:48:57 -0500 From: Mike Rylander Reply-To: Mike Rylander To: Richard Rowell Subject: Re: Breadth first traversal in PLSQL (How to implement Queue?) Cc: PostgreSQL SQL In-Reply-To: <1103136884.9908.22.camel@richard> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit References: <1103136884.9908.22.camel@richard> X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.213 tagged_above=0 required=5 tests=AWL, RCVD_BY_IP, UPPERCASE_25_50 X-Spam-Level: X-Archive-Number: 200412/97 X-Sequence-Number: 19717 On Wed, 15 Dec 2004 12:54:44 -0600, Richard Rowell wrote: > I have a table with a unary (recursive) relationship that represents a > hierarchy. With the gracious help of Mike Rylander I was able to port a > TSQL function that would traverse "up" the hierarchy to PL/SQL. Now I > need help porting the "down" the hierarchy function. Glad I could help! > > As implemented in TSQL I utilized a simple breadth first tree traversal. > I'm not sure how to replicate this in PL/SQL as I haven't figured out > how to implement the queue required for the breadth first algorithm. My > queue is declared "queue SETOF INTEGER" and I'm able to "SELECT INTO" > this variable. However when I try to delete the "current" value, I get > a syntax error. If I comment the delete out, I also get an error when I > try to fetch the "next" value from the front of the queue. > You probably want to use a temp table to hold the queue. Edits inline below. > Below is the function, followed by the psql output: > > CREATE OR REPLACE FUNCTION svp_getchildproviderids (INTEGER) > RETURNS SETOF INTEGER > AS ' > DECLARE > parent_provider ALIAS FOR $1; > cid INTEGER; -- Comment out the next line... -- queue SETOF INTEGER; > BEGIN -- We need to use execute to create the queue, otherwise -- the OID will be cached and the next invocation will cause -- an exception. EXECUTE ''CREATE TEMP TABLE cid_queue (id SERIAL, cid INTEGER ) WITHOUT OIDS;''; > SELECT INTO cid count(*) FROM providers WHERE uid =parent_provider; > IF cid = 0 THEN > RAISE EXCEPTION ''Inexistent ID --> %'', parent_provider; > RETURN; > END IF; > cid := parent_provider; > LOOP > EXIT WHEN cid IS NULL; > RETURN NEXT cid; -- Put the CID into the queue EXECUTE ''INSERT INTO cid_queue VALUES ((SELECT uid FROM providers WHERE parent_id = '' || quote_literal( cid ) || ''));''; -- We'll use EXECUTE to delete the current cid from the queue EXECUTE ''DELETE FROM cid_queue WHERE cid = '' || quote_literal( cid ) || '';''; -- And a short loop to grab the next one FOR cid IN EXECUTE ''SELECT cid FROM cid_queue ORDER BY id LIMIT 1;'' END LOOP; > END LOOP; > RETURN; > END;' LANGUAGE 'plpgsql'; Let me know if that works. As before, it's untested, so YMMV... :) -- Mike Rylander mrylander@gmail.com GPLS -- PINES Development Database Developer http://open-ils.org