Re: Function Temp Table Woes - Mailing list pgsql-sql

From Chad Voelker
Subject Re: Function Temp Table Woes
Date
Msg-id 20060810115233.32189.qmail@web31212.mail.mud.yahoo.com
Whole thread Raw
In response to Re: Function Temp Table Woes  (Michael Fuhr <mike@fuhr.org>)
List pgsql-sql
Michael-

Nice explaination of what was happening to the temp
table. 

Thank you.
-Chad

--- Michael Fuhr <mike@fuhr.org> 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 <tablename>".
> 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 <tablename> ...
> INSERT INTO <tablename> 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 


pgsql-sql by date:

Previous
From: John DeSoi
Date:
Subject: Re: [PHP] PL/pgSQL and PHP 5
Next
From: "Andrew Hammond"
Date:
Subject: Re: timestamp (MS SQLServer's rowversion) functionality