X-Original-To: pgsql-sql-postgresql.org@postgresql.org Received: from localhost (mx1.hub.org [200.46.208.251]) by postgresql.org (Postfix) with ESMTP id AE1569FB2A6 for ; Thu, 10 Aug 2006 08:52:38 -0300 (ADT) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.208.251]) (amavisd-new, port 10024) with ESMTP id 75835-05 for ; Thu, 10 Aug 2006 08:52:34 -0300 (ADT) X-Greylist: domain auto-whitelisted by SQLgrey- Received: from web31212.mail.mud.yahoo.com (web31212.mail.mud.yahoo.com [68.142.201.78]) by postgresql.org (Postfix) with SMTP id A5F959FB269 for ; Thu, 10 Aug 2006 08:52:34 -0300 (ADT) Received: (qmail 32191 invoked by uid 60001); 10 Aug 2006 11:52:33 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.com; h=Message-ID:Received:Date:From:Subject:To:In-Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding; b=mQjtOJePPXIki8V8L9/s9u/wAxx8PKQ9HWzFYUW69ga51bvooNT3UnGmCpCtMESV4ZniV4XOdz9ZzF+Ng+kh9Djqd1AnnATuNO7HKgZwdf2fOJ/2sMuCSqTH2LDWPOYjOJGZ0ApztW5hWU2ShFgN6bEV9DDNFMmUy3RUdmDGcsY= ; Message-ID: <20060810115233.32189.qmail@web31212.mail.mud.yahoo.com> Received: from [167.79.56.136] by web31212.mail.mud.yahoo.com via HTTP; Thu, 10 Aug 2006 04:52:33 PDT Date: Thu, 10 Aug 2006 04:52:33 -0700 (PDT) From: Chad Voelker Subject: Re: Function Temp Table Woes To: pgsql-sql@postgresql.org In-Reply-To: <20060809021247.GA14345@winnie.fuhr.org> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=1.778 tagged_above=0 required=5 tests=AWL, DNS_FROM_RFC_ABUSE, DNS_FROM_RFC_POST, DNS_FROM_RFC_WHOIS X-Spam-Level: * X-Archive-Number: 200608/60 X-Sequence-Number: 26018 Michael- Nice explaination of what was happening to the temp table. Thank you. -Chad --- Michael Fuhr wrote: > On Tue, Aug 08, 2006 at 10:24:02AM -0700, Chad > Voelker wrote: > > The Goal: Return a set of records from one table > based > > on entries in a temporary table. I'd expect this > to be > > a commonly requested functionality. After reading > the > > docs, support lists and googling, I haven't come > up > > with a clean solution. My query is at the end of > this > > post. > > > > I've come to the conclusion that returning a > REFCURSOR > > is the best approach, but I will take other > suggestions. > > A set-returning function would probably be easier to > use; search > for examples of functions declared with "RETURNS > SETOF ". > Using views instead of a function might also be > possible. > > > My current issue is that the temp table > (tt_occ_units) is > > not being dropped after commit. The second calling > of this > > function produces the 'relation already exists' > error. > > The temporary table is indeed being dropped; the > problem is that > the function creates another non-temporary table > with the same name > and that table isn't being dropped: > > > CREATE TEMP TABLE tt_occ_units (unit_id > INTEGER) > > ON COMMIT DROP; > > -- Get ids for all available units > > SELECT u.id INTO tt_occ_units > > The first command above creates the temporary table > but then SELECT > INTO creates the non-temporary table with the same > name but in a > different schema. Here's a simple example that > shows what's happening: > > CREATE FUNCTION test() RETURNS void AS $$ > BEGIN > CREATE TEMP TABLE foo (x integer) ON COMMIT > DROP; > SELECT x INTO foo FROM (SELECT 1::integer AS x) > AS s; > END; > $$ LANGUAGE plpgsql; > > test=> \dt *.foo > No matching relations found. > test=> BEGIN; > BEGIN > test=> SELECT test(); > test > ------ > > (1 row) > > test=> \dt *.foo > List of relations > Schema | Name | Type | Owner > -----------+------+-------+------- > pg_temp_1 | foo | table | mfuhr > public | foo | table | mfuhr > (2 rows) > > test=> COMMIT; > COMMIT > test=> \dt *.foo > List of relations > Schema | Name | Type | Owner > --------+------+-------+------- > public | foo | table | mfuhr > (1 row) > > Notice that the temporary table went away after the > commit but that > the non-temporary table remained -- that's the table > that's giving > you trouble. Instead of using SELECT INTO you could > use INSERT > with a query, like this: > > CREATE TEMP TABLE ... > INSERT INTO SELECT ... > > However, this still has a problem: after the first > time you call > the function subsequent calls will fail with > "relation with OID > XXXXX does not exist." See the FAQ for the reason > and how to avoid > it: > > http://www.postgresql.org/docs/faqs.FAQ.html#item4.19 > > Instead of using a temporary table, consider > incorporating that > query directly into the main query/queries. > > -- > Michael Fuhr > __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com