Thread: call the same pl/pgsql procedure twice in the same connection session

I have a function with pl/pgSQL such as...
CREATE FUNCTION comp_userExp (TEXT) RETURNS INTEGER  AS '
DECLAREstUserName TEXT;
BEGINstUserName := upper($1);
CREATE TEMP TABLE comuser AS SELECT * FROM comt_user1 WHERE userName=stUserName;
CREATE TEMP TABLE comUser1 AS SELECT a.userName FROM comt_user2 a, comuser b WHERE a.userName = b.userName ORDER BY
b.userName;
CREATE TEMP TABLE comUser2 AS SELECT a.userName FROM comt_user3 a, comuser b WHERE a.userName = b.userName ORDER BY
b.userName;
DROP Table comuser,comuser1,comuser2;
RETURN 0;

END;' LANGUAGE 'PLPGSQL';

This function can't run twice in the same connection session. After tracing
error, the reason is because 2nd and 3rd SQL refer to table comuser. It will
cause "can't find relation number xxxxx". I think ,after first run, the
procedure just use relation number to access table, while actually table was
dropped and create again with a different relation number on the 2nd time.
If I disconnect database, and re-connect again, it won't cuase any problem.
If don't want to disconnect and connect, is there any way to fix the
problem?

JACK
JACK



Re: call the same pl/pgsql procedure twice in the same connection

From
Bruce Momjian
Date:
jack wrote:
> I have a function with pl/pgSQL such as...
> CREATE FUNCTION comp_userExp (TEXT) RETURNS INTEGER  AS '
> DECLARE
>  stUserName TEXT;
> BEGIN
>  stUserName := upper($1);
> 
>  CREATE TEMP TABLE comuser AS
>   SELECT * FROM comt_user1
>   WHERE userName=stUserName;
> 
>  CREATE TEMP TABLE comUser1 AS
>   SELECT a.userName FROM comt_user2 a, comuser b
>   WHERE a.userName = b.userName
>   ORDER BY b.userName;
> 
>  CREATE TEMP TABLE comUser2 AS
>   SELECT a.userName FROM comt_user3 a, comuser b
>   WHERE a.userName = b.userName
>   ORDER BY b.userName;
> 
>  DROP Table comuser,comuser1,comuser2;
> 
>  RETURN 0;
> 
> END;'
>   LANGUAGE 'PLPGSQL';
> 
> This function can't run twice in the same connection session. After tracing
> error, the reason is because 2nd and 3rd SQL refer to table comuser. It will
> cause "can't find relation number xxxxx". I think ,after first run, the
> procedure just use relation number to access table, while actually table was
> dropped and create again with a different relation number on the 2nd time.
> If I disconnect database, and re-connect again, it won't cuase any problem.
> If don't want to disconnect and connect, is there any way to fix the
> problem?

Yes, this is coming up a lot recently, maybe an FAQ.  You need to use
EXECUTE in plpgsql so the string is reparsed every time and the proper
oid assigned.

--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
853-3000+  If your life is a hard drive,     |  830 Blythe Avenue +  Christ can be your backup.        |  Drexel Hill,
Pennsylvania19026
 


Re: call the same pl/pgsql procedure twice in the same connection

From
Jan Wieck
Date:
Bruce Momjian wrote:
> jack wrote:
> > I have a function with pl/pgSQL such as...
> > CREATE FUNCTION comp_userExp (TEXT) RETURNS INTEGER  AS '
> > DECLARE
> >  stUserName TEXT;
> > BEGIN
> >  stUserName := upper($1);
> >
> >  CREATE TEMP TABLE comuser AS
> >   SELECT * FROM comt_user1
> >   WHERE userName=stUserName;
> >
> >  CREATE TEMP TABLE comUser1 AS
> >   SELECT a.userName FROM comt_user2 a, comuser b
> >   WHERE a.userName = b.userName
> >   ORDER BY b.userName;
> >
> >  CREATE TEMP TABLE comUser2 AS
> >   SELECT a.userName FROM comt_user3 a, comuser b
> >   WHERE a.userName = b.userName
> >   ORDER BY b.userName;
> >
> >  DROP Table comuser,comuser1,comuser2;
> >
> >  RETURN 0;
> >
> > END;'
> >   LANGUAGE 'PLPGSQL';
> >
> > This function can't run twice in the same connection session. After tracing
> > error, the reason is because 2nd and 3rd SQL refer to table comuser. It will
> > cause "can't find relation number xxxxx". I think ,after first run, the
> > procedure just use relation number to access table, while actually table was
> > dropped and create again with a different relation number on the 2nd time.
> > If I disconnect database, and re-connect again, it won't cuase any problem.
> > If don't want to disconnect and connect, is there any way to fix the
> > problem?
>
> Yes, this is coming up a lot recently, maybe an FAQ.  You need to use
> EXECUTE in plpgsql so the string is reparsed every time and the proper
> oid assigned.
   This  is  somehow connected to the temporary view discussion,   as it  needs  the  same  detection  if  a  query
depends on   temporary  objects.  As soon as we have a detection mechanism   for it, I can modify PL/pgSQL not to save
preparedplans  for   these statements.
 


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #



_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com



Re: call the same pl/pgsql procedure twice in the same connection

From
Tom Lane
Date:
Jan Wieck <janwieck@yahoo.com> writes:
>     This  is  somehow connected to the temporary view discussion,
>     as it  needs  the  same  detection  if  a  query  depends  on
>     temporary  objects.  As soon as we have a detection mechanism
>     for it, I can modify PL/pgSQL not to save prepared plans  for
>     these statements.

Actually, I don't think plpgsql should make any special discrimination
against temp tables; it should be able to re-use a query plan for
exactly as long as the temp table exists.  But I agree that we need
a mechanism for tracking query-plan dependencies for this to happen.
        regards, tom lane


Re: call the same pl/pgsql procedure twice in the same connection

From
Bruce Momjian
Date:
Jan, instead of doing cache invalidation to fix temporary tables, can we
disable cached plans for functions that use temporary tables?

---------------------------------------------------------------------------

Jan Wieck wrote:
> Bruce Momjian wrote:
> > jack wrote:
> > > I have a function with pl/pgSQL such as...
> > > CREATE FUNCTION comp_userExp (TEXT) RETURNS INTEGER  AS '
> > > DECLARE
> > >  stUserName TEXT;
> > > BEGIN
> > >  stUserName := upper($1);
> > >
> > >  CREATE TEMP TABLE comuser AS
> > >   SELECT * FROM comt_user1
> > >   WHERE userName=stUserName;
> > >
> > >  CREATE TEMP TABLE comUser1 AS
> > >   SELECT a.userName FROM comt_user2 a, comuser b
> > >   WHERE a.userName = b.userName
> > >   ORDER BY b.userName;
> > >
> > >  CREATE TEMP TABLE comUser2 AS
> > >   SELECT a.userName FROM comt_user3 a, comuser b
> > >   WHERE a.userName = b.userName
> > >   ORDER BY b.userName;
> > >
> > >  DROP Table comuser,comuser1,comuser2;
> > >
> > >  RETURN 0;
> > >
> > > END;'
> > >   LANGUAGE 'PLPGSQL';
> > >
> > > This function can't run twice in the same connection session. After tracing
> > > error, the reason is because 2nd and 3rd SQL refer to table comuser. It will
> > > cause "can't find relation number xxxxx". I think ,after first run, the
> > > procedure just use relation number to access table, while actually table was
> > > dropped and create again with a different relation number on the 2nd time.
> > > If I disconnect database, and re-connect again, it won't cuase any problem.
> > > If don't want to disconnect and connect, is there any way to fix the
> > > problem?
> >
> > Yes, this is coming up a lot recently, maybe an FAQ.  You need to use
> > EXECUTE in plpgsql so the string is reparsed every time and the proper
> > oid assigned.
> 
>     This  is  somehow connected to the temporary view discussion,
>     as it  needs  the  same  detection  if  a  query  depends  on
>     temporary  objects.  As soon as we have a detection mechanism
>     for it, I can modify PL/pgSQL not to save prepared plans  for
>     these statements.
> 
> 
> Jan
> 
> --
> 
> #======================================================================#
> # It's easier to get forgiveness for being wrong than for being right. #
> # Let's break this rule - forgive me.                                  #
> #================================================== JanWieck@Yahoo.com #
> 
> 
> 
> _________________________________________________________
> Do You Yahoo!?
> Get your free @yahoo.com address at http://mail.yahoo.com
> 
> 

--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
853-3000+  If your life is a hard drive,     |  830 Blythe Avenue +  Christ can be your backup.        |  Drexel Hill,
Pennsylvania19026
 


Re: call the same pl/pgsql procedure twice in the same connection

From
Jan Wieck
Date:
Bruce Momjian wrote:
>
> Jan, instead of doing cache invalidation to fix temporary tables, can we
> disable cached plans for functions that use temporary tables?
   I  was  thinking  of  a different approach. Enhancing the SPI   manager to detect if a plan uses  temporary  objects
and  to   remember  the  original  querystring  in the SPI_plan. Having   callbacks when temp object  beeing  destroyed
into  the  SPI   manager,  causing  it to reparse and plan on the next call to   SPI_execp() would do it for everything
thatuses SPI.
 


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #




Re: call the same pl/pgsql procedure twice in the same connection

From
Bruce Momjian
Date:
Jan Wieck wrote:
> Bruce Momjian wrote:
> >
> > Jan, instead of doing cache invalidation to fix temporary tables, can we
> > disable cached plans for functions that use temporary tables?
> 
>     I  was  thinking  of  a different approach. Enhancing the SPI
>     manager to detect if a plan uses  temporary  objects  and  to
>     remember  the  original  querystring  in the SPI_plan. Having
>     callbacks when temp object  beeing  destroyed  into  the  SPI
>     manager,  causing  it to reparse and plan on the next call to
>     SPI_execp() would do it for everything that uses SPI.

I was merely proposing that preventing caching of functions ueing temp
tables may be easier than trying to invalidation them on temp table
destruction.

--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
853-3000+  If your life is a hard drive,     |  830 Blythe Avenue +  Christ can be your backup.        |  Drexel Hill,
Pennsylvania19026
 


Re: call the same pl/pgsql procedure twice in the same connection

From
Jan Wieck
Date:
Bruce Momjian wrote:
> Jan Wieck wrote:
> > Bruce Momjian wrote:
> > >
> > > Jan, instead of doing cache invalidation to fix temporary tables, can we
> > > disable cached plans for functions that use temporary tables?
> >
> >     I  was  thinking  of  a different approach. Enhancing the SPI
> >     manager to detect if a plan uses  temporary  objects  and  to
> >     remember  the  original  querystring  in the SPI_plan. Having
> >     callbacks when temp object  beeing  destroyed  into  the  SPI
> >     manager,  causing  it to reparse and plan on the next call to
> >     SPI_execp() would do it for everything that uses SPI.
>
> I was merely proposing that preventing caching of functions ueing temp
> tables may be easier than trying to invalidation them on temp table
> destruction.
   It's neat to say "preventing caching of functions using ...",   now tell in detail how you detect that a function
"is" using   a  temp table?  No, I don't mean how "you" can detect it, how   can the PL/pgSQL parser or executor detect
it. And  when  do   you  detect  it?  Remember  that  PL/pgSQL  has  delayed  SPI   preparation?
 
   Second, it doesn't really look smart to me to prevent  saving   of  all  query  plans  just  because  one of them
usesa temp   table.
 


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #




Re: call the same pl/pgsql procedure twice in the same connection

From
Richard Huxton
Date:
On Thursday 18 April 2002 17:43, Jan Wieck wrote:
> Bruce Momjian wrote:
> > Jan, instead of doing cache invalidation to fix temporary tables, can we
> > disable cached plans for functions that use temporary tables?
>
>     I  was  thinking  of  a different approach. Enhancing the SPI
>     manager to detect if a plan uses  temporary  objects
...

Was there not some talk of tracking dependencies between all objects (to avoid 
the problems with dropping referenced tables/functions). If so, it sounds 
like this is part of that future things job.

- Richard Huxton


Re: call the same pl/pgsql procedure twice in the same connection

From
Bruce Momjian
Date:
Jan Wieck wrote:
> Bruce Momjian wrote:
> > Jan Wieck wrote:
> > > Bruce Momjian wrote:
> > > >
> > > > Jan, instead of doing cache invalidation to fix temporary tables, can we
> > > > disable cached plans for functions that use temporary tables?
> > >
> > >     I  was  thinking  of  a different approach. Enhancing the SPI
> > >     manager to detect if a plan uses  temporary  objects  and  to
> > >     remember  the  original  querystring  in the SPI_plan. Having
> > >     callbacks when temp object  beeing  destroyed  into  the  SPI
> > >     manager,  causing  it to reparse and plan on the next call to
> > >     SPI_execp() would do it for everything that uses SPI.
> >
> > I was merely proposing that preventing caching of functions ueing temp
> > tables may be easier than trying to invalidation them on temp table
> > destruction.
> 
>     It's neat to say "preventing caching of functions using ...",
>     now tell in detail how you detect that a function "is"  using
>     a  temp table?  No, I don't mean how "you" can detect it, how
>     can the PL/pgSQL parser or executor detect it.  And  when  do
>     you  detect  it?  Remember  that  PL/pgSQL  has  delayed  SPI
>     preparation?
> 
>     Second, it doesn't really look smart to me to prevent  saving
>     of  all  query  plans  just  because  one of them uses a temp
>     table.

Well, I assume you could spin through the plan at save time and look at
every relation reference to see if it is a temp table.

--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
853-3000+  If your life is a hard drive,     |  830 Blythe Avenue +  Christ can be your backup.        |  Drexel Hill,
Pennsylvania19026
 


Re: call the same pl/pgsql procedure twice in the same connection

From
Jan Wieck
Date:
Bruce Momjian wrote:
> Jan Wieck wrote:
> > Bruce Momjian wrote:
> > > Jan Wieck wrote:
> > > > Bruce Momjian wrote:
> > > > >
> > > > > Jan, instead of doing cache invalidation to fix temporary tables, can we
> > > > > disable cached plans for functions that use temporary tables?
> > > >
> > > >     I  was  thinking  of  a different approach. Enhancing the SPI
> > > >     manager to detect if a plan uses  temporary  objects  and  to
> > > >     remember  the  original  querystring  in the SPI_plan. Having
> > > >     callbacks when temp object  beeing  destroyed  into  the  SPI
> > > >     manager,  causing  it to reparse and plan on the next call to
> > > >     SPI_execp() would do it for everything that uses SPI.
> > >
> > > I was merely proposing that preventing caching of functions ueing temp
> > > tables may be easier than trying to invalidation them on temp table
> > > destruction.
> >
> >     It's neat to say "preventing caching of functions using ...",
> >     now tell in detail how you detect that a function "is"  using
> >     a  temp table?  No, I don't mean how "you" can detect it, how
> >     can the PL/pgSQL parser or executor detect it.  And  when  do
> >     you  detect  it?  Remember  that  PL/pgSQL  has  delayed  SPI
> >     preparation?
> >
> >     Second, it doesn't really look smart to me to prevent  saving
> >     of  all  query  plans  just  because  one of them uses a temp
> >     table.
>
> Well, I assume you could spin through the plan at save time and look at
> every relation reference to see if it is a temp table.

Bruce,
   you are really good at making things sound simple by stopping   half way through.
   Your  assumption  is  exactly  my  "detect  if  a  plan  uses   temporary objects". No go on, what exactly are you
doingwith   the information that the plan uses a temp table?
 
   And BTW, since you are the one who invented temp tables,  how   does someone detect a temp table?


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #




Re: call the same pl/pgsql procedure twice in the same connection

From
Bruce Momjian
Date:
Jan Wieck wrote:
>     you are really good at making things sound simple by stopping
>     half way through.

Sure.  How do you think I got so far.  :-)


>     Your  assumption  is  exactly  my  "detect  if  a  plan  uses
>     temporary objects". No go on, what exactly are you doing with
>     the information that the plan uses a temp table?

If it uses a temp table, run the plan and discard it, don't save the
plan in the cache.

>     And BTW, since you are the one who invented temp tables,  how
>     does someone detect a temp table?

You have to call a macro on the relnames used in the plan.  Before
schemas, it was just a macro.   Now that Tom has them in schemas, I am
not sure how to detect them, but I assume they are in a separate schema.
Looks like he created FindTempRelations() that returns a list of temp
relations.

--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
853-3000+  If your life is a hard drive,     |  830 Blythe Avenue +  Christ can be your backup.        |  Drexel Hill,
Pennsylvania19026