Re: [PATCHES] "fix" for plpgsql polymorphism

2003-07-26 Thread Bruce Momjian

Patch applied.  Thanks.

---



Joe Conway wrote:
> Tom Lane wrote:
> >>You can alias $0, similar to the argument variables. And, I confirmed 
> >>that you cannot change the value, similar to the argument variables:
> > 
> > Perhaps you shouldn't mark it isconst; then it would actually have some
> > usefulness (you could use it directly as a temporary variable to hold
> > the intended result).  I can't see much value in aliasing it if it's
> > const, either.
> 
> OK; the only change in this version is "isconst = false;". Now you can 
> use $0 as a result placeholder if desired. E.g.:
> 
> create or replace function tmp(anyelement, anyelement) returns anyarray as '
> declare
>   v_ret alias for $0;
>   v_el1 alias for $1;
>   v_el2 alias for $2;
> begin
>   v_ret := ARRAY[v_el1, v_el2];
>   return v_ret;
> end;
> ' language 'plpgsql';
> 
> create table f(f1 text, f2 text, f3 int, f4 int);
> insert into f values ('a','b',1,2);
> insert into f values ('z','x',3,4);
> 
> select tmp(f1,f2) from f;
> select tmp(f3,f4) from f;
> 
> Joe

> Index: src/pl/plpgsql/src/pl_comp.c
> ===
> RCS file: /opt/src/cvs/pgsql-server/src/pl/plpgsql/src/pl_comp.c,v
> retrieving revision 1.59
> diff -c -r1.59 pl_comp.c
> *** src/pl/plpgsql/src/pl_comp.c  1 Jul 2003 21:47:09 -   1.59
> --- src/pl/plpgsql/src/pl_comp.c  3 Jul 2003 17:59:48 -
> ***
> *** 354,359 
> --- 354,395 
>   function->fn_rettyplen = typeStruct->typlen;
>   function->fn_rettypelem = typeStruct->typelem;
>   perm_fmgr_info(typeStruct->typinput, 
> &(function->fn_retinput));
> + 
> + /*
> +  * install $0 reference, but only for polymorphic
> +  * return types
> +  */
> + if (procStruct->prorettype == ANYARRAYOID ||
> + procStruct->prorettype == ANYELEMENTOID)
> + {
> + charbuf[32];
> + 
> + /* name for variable */
> + snprintf(buf, sizeof(buf), "$%d", 0);
> + 
> + /*
> +  * Normal return values get a var node
> +  */
> + var = malloc(sizeof(PLpgSQL_var));
> + memset(var, 0, sizeof(PLpgSQL_var));
> + 
> + var->dtype = PLPGSQL_DTYPE_VAR;
> + var->refname = strdup(buf);
> + var->lineno = 0;
> + var->datatype = build_datatype(typeTup, -1);
> + var->isconst = false;
> + var->notnull = false;
> + var->default_val = NULL;
> + 
> + /* preset to NULL */
> + var->value = 0;
> + var->isnull = true;
> + var->freeval = false;
> + 
> + plpgsql_adddatum((PLpgSQL_datum *) var);
> + plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, 
> var->varno,
> +
> var->refname);
> + }
>   }
>   ReleaseSysCache(typeTup);
>   

> 
> ---(end of broadcast)---
> TIP 4: Don't 'kill -9' the postmaster

-- 
  Bruce Momjian|  http://candle.pha.pa.us
  [EMAIL PROTECTED]   |  (610) 359-1001
  +  If your life is a hard drive, |  13 Roberts Road
  +  Christ can be your backup.|  Newtown Square, Pennsylvania 19073

---(end of broadcast)---
TIP 8: explain analyze is your friend


Re: [PATCHES] "fix" for plpgsql polymorphism

2003-07-20 Thread Bruce Momjian

Your patch has been added to the PostgreSQL unapplied patches list at:

http://momjian.postgresql.org/cgi-bin/pgpatches

I will try to apply it within the next 48 hours.

---


Joe Conway wrote:
> Tom Lane wrote:
> >>You can alias $0, similar to the argument variables. And, I confirmed 
> >>that you cannot change the value, similar to the argument variables:
> > 
> > Perhaps you shouldn't mark it isconst; then it would actually have some
> > usefulness (you could use it directly as a temporary variable to hold
> > the intended result).  I can't see much value in aliasing it if it's
> > const, either.
> 
> OK; the only change in this version is "isconst = false;". Now you can 
> use $0 as a result placeholder if desired. E.g.:
> 
> create or replace function tmp(anyelement, anyelement) returns anyarray as '
> declare
>   v_ret alias for $0;
>   v_el1 alias for $1;
>   v_el2 alias for $2;
> begin
>   v_ret := ARRAY[v_el1, v_el2];
>   return v_ret;
> end;
> ' language 'plpgsql';
> 
> create table f(f1 text, f2 text, f3 int, f4 int);
> insert into f values ('a','b',1,2);
> insert into f values ('z','x',3,4);
> 
> select tmp(f1,f2) from f;
> select tmp(f3,f4) from f;
> 
> Joe

> Index: src/pl/plpgsql/src/pl_comp.c
> ===
> RCS file: /opt/src/cvs/pgsql-server/src/pl/plpgsql/src/pl_comp.c,v
> retrieving revision 1.59
> diff -c -r1.59 pl_comp.c
> *** src/pl/plpgsql/src/pl_comp.c  1 Jul 2003 21:47:09 -   1.59
> --- src/pl/plpgsql/src/pl_comp.c  3 Jul 2003 17:59:48 -
> ***
> *** 354,359 
> --- 354,395 
>   function->fn_rettyplen = typeStruct->typlen;
>   function->fn_rettypelem = typeStruct->typelem;
>   perm_fmgr_info(typeStruct->typinput, 
> &(function->fn_retinput));
> + 
> + /*
> +  * install $0 reference, but only for polymorphic
> +  * return types
> +  */
> + if (procStruct->prorettype == ANYARRAYOID ||
> + procStruct->prorettype == ANYELEMENTOID)
> + {
> + charbuf[32];
> + 
> + /* name for variable */
> + snprintf(buf, sizeof(buf), "$%d", 0);
> + 
> + /*
> +  * Normal return values get a var node
> +  */
> + var = malloc(sizeof(PLpgSQL_var));
> + memset(var, 0, sizeof(PLpgSQL_var));
> + 
> + var->dtype = PLPGSQL_DTYPE_VAR;
> + var->refname = strdup(buf);
> + var->lineno = 0;
> + var->datatype = build_datatype(typeTup, -1);
> + var->isconst = false;
> + var->notnull = false;
> + var->default_val = NULL;
> + 
> + /* preset to NULL */
> + var->value = 0;
> + var->isnull = true;
> + var->freeval = false;
> + 
> + plpgsql_adddatum((PLpgSQL_datum *) var);
> + plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, 
> var->varno,
> +
> var->refname);
> + }
>   }
>   ReleaseSysCache(typeTup);
>   

> 
> ---(end of broadcast)---
> TIP 4: Don't 'kill -9' the postmaster

-- 
  Bruce Momjian|  http://candle.pha.pa.us
  [EMAIL PROTECTED]   |  (610) 359-1001
  +  If your life is a hard drive, |  13 Roberts Road
  +  Christ can be your backup.|  Newtown Square, Pennsylvania 19073

---(end of broadcast)---
TIP 3: if posting/reading through Usenet, please send an appropriate
  subscribe-nomail command to [EMAIL PROTECTED] so that your
  message can get through to the mailing list cleanly


Re: [PATCHES] "fix" for plpgsql polymorphism

2003-07-18 Thread Joe Conway
I'm going to resend the patches that I have outstanding since it appears 
some may have been lost. Here's the first.
==

Tom Lane wrote:
You can alias $0, similar to the argument variables. And, I confirmed 
that you cannot change the value, similar to the argument variables:
Perhaps you shouldn't mark it isconst; then it would actually have some
usefulness (you could use it directly as a temporary variable to hold
the intended result).  I can't see much value in aliasing it if it's
const, either.
OK; the only change in this version is "isconst = false;". Now you can
use $0 as a result placeholder if desired. E.g.:
create or replace function tmp(anyelement, anyelement) returns anyarray as '
declare
  v_ret alias for $0;
  v_el1 alias for $1;
  v_el2 alias for $2;
begin
  v_ret := ARRAY[v_el1, v_el2];
  return v_ret;
end;
' language 'plpgsql';
create table f(f1 text, f2 text, f3 int, f4 int);
insert into f values ('a','b',1,2);
insert into f values ('z','x',3,4);
select tmp(f1,f2) from f;
select tmp(f3,f4) from f;
Joe

Index: src/pl/plpgsql/src/pl_comp.c
===
RCS file: /opt/src/cvs/pgsql-server/src/pl/plpgsql/src/pl_comp.c,v
retrieving revision 1.59
diff -c -r1.59 pl_comp.c
*** src/pl/plpgsql/src/pl_comp.c1 Jul 2003 21:47:09 -   1.59
--- src/pl/plpgsql/src/pl_comp.c3 Jul 2003 17:59:48 -
***
*** 354,359 
--- 354,395 
function->fn_rettyplen = typeStruct->typlen;
function->fn_rettypelem = typeStruct->typelem;
perm_fmgr_info(typeStruct->typinput, 
&(function->fn_retinput));
+ 
+   /*
+* install $0 reference, but only for polymorphic
+* return types
+*/
+   if (procStruct->prorettype == ANYARRAYOID ||
+   procStruct->prorettype == ANYELEMENTOID)
+   {
+   charbuf[32];
+ 
+   /* name for variable */
+   snprintf(buf, sizeof(buf), "$%d", 0);
+ 
+   /*
+* Normal return values get a var node
+*/
+   var = malloc(sizeof(PLpgSQL_var));
+   memset(var, 0, sizeof(PLpgSQL_var));
+ 
+   var->dtype = PLPGSQL_DTYPE_VAR;
+   var->refname = strdup(buf);
+   var->lineno = 0;
+   var->datatype = build_datatype(typeTup, -1);
+   var->isconst = false;
+   var->notnull = false;
+   var->default_val = NULL;
+ 
+   /* preset to NULL */
+   var->value = 0;
+   var->isnull = true;
+   var->freeval = false;
+ 
+   plpgsql_adddatum((PLpgSQL_datum *) var);
+   plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, 
var->varno,
+  
var->refname);
+   }
}
ReleaseSysCache(typeTup);
  


---(end of broadcast)---
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]


Re: [PATCHES] "fix" for plpgsql polymorphism

2003-07-03 Thread Christopher Kings-Lynne
> OK; the only change in this version is "isconst = false;". Now you can
> use $0 as a result placeholder if desired. E.g.:

Can we get any inspiration from Perl or bash here?  eg. $$ or $* or
whatever?

Chris


---(end of broadcast)---
TIP 4: Don't 'kill -9' the postmaster


Re: [PATCHES] "fix" for plpgsql polymorphism

2003-07-03 Thread Joe Conway
Tom Lane wrote:
You can alias $0, similar to the argument variables. And, I confirmed 
that you cannot change the value, similar to the argument variables:
Perhaps you shouldn't mark it isconst; then it would actually have some
usefulness (you could use it directly as a temporary variable to hold
the intended result).  I can't see much value in aliasing it if it's
const, either.
OK; the only change in this version is "isconst = false;". Now you can 
use $0 as a result placeholder if desired. E.g.:

create or replace function tmp(anyelement, anyelement) returns anyarray as '
declare
 v_ret alias for $0;
 v_el1 alias for $1;
 v_el2 alias for $2;
begin
 v_ret := ARRAY[v_el1, v_el2];
 return v_ret;
end;
' language 'plpgsql';
create table f(f1 text, f2 text, f3 int, f4 int);
insert into f values ('a','b',1,2);
insert into f values ('z','x',3,4);
select tmp(f1,f2) from f;
select tmp(f3,f4) from f;
Joe
Index: src/pl/plpgsql/src/pl_comp.c
===
RCS file: /opt/src/cvs/pgsql-server/src/pl/plpgsql/src/pl_comp.c,v
retrieving revision 1.59
diff -c -r1.59 pl_comp.c
*** src/pl/plpgsql/src/pl_comp.c1 Jul 2003 21:47:09 -   1.59
--- src/pl/plpgsql/src/pl_comp.c3 Jul 2003 17:59:48 -
***
*** 354,359 
--- 354,395 
function->fn_rettyplen = typeStruct->typlen;
function->fn_rettypelem = typeStruct->typelem;
perm_fmgr_info(typeStruct->typinput, 
&(function->fn_retinput));
+ 
+   /*
+* install $0 reference, but only for polymorphic
+* return types
+*/
+   if (procStruct->prorettype == ANYARRAYOID ||
+   procStruct->prorettype == ANYELEMENTOID)
+   {
+   charbuf[32];
+ 
+   /* name for variable */
+   snprintf(buf, sizeof(buf), "$%d", 0);
+ 
+   /*
+* Normal return values get a var node
+*/
+   var = malloc(sizeof(PLpgSQL_var));
+   memset(var, 0, sizeof(PLpgSQL_var));
+ 
+   var->dtype = PLPGSQL_DTYPE_VAR;
+   var->refname = strdup(buf);
+   var->lineno = 0;
+   var->datatype = build_datatype(typeTup, -1);
+   var->isconst = false;
+   var->notnull = false;
+   var->default_val = NULL;
+ 
+   /* preset to NULL */
+   var->value = 0;
+   var->isnull = true;
+   var->freeval = false;
+ 
+   plpgsql_adddatum((PLpgSQL_datum *) var);
+   plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, 
var->varno,
+  
var->refname);
+   }
}
ReleaseSysCache(typeTup);
  

---(end of broadcast)---
TIP 4: Don't 'kill -9' the postmaster


Re: [PATCHES] "fix" for plpgsql polymorphism

2003-07-03 Thread Tom Lane
Joe Conway <[EMAIL PROTECTED]> writes:
> Tom Lane wrote:
>> I'm not excited about picking a notation for the long term on the
>> grounds that it takes the least code to implement today.

> I knew you wouldn't be ;-)

>> I admit I have not got a clearly-better solution in my hip pocket,
>> but "$0" is just rubbing my design sense the wrong way.

> Yeah, me too, but then I didn't particularly like plpgsql's $1, $2, ... 
> notation for arguments at first either. If we had named arguments, then 
> this wouldn't even be a consideration in my mind, but given that we 
> don't, I still think it is the best choice.

> You can alias $0, similar to the argument variables. And, I confirmed 
> that you cannot change the value, similar to the argument variables:

Perhaps you shouldn't mark it isconst; then it would actually have some
usefulness (you could use it directly as a temporary variable to hold
the intended result).  I can't see much value in aliasing it if it's
const, either.

regards, tom lane

---(end of broadcast)---
TIP 2: you can get off all lists at once with the unregister command
(send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])


Re: [PATCHES] "fix" for plpgsql polymorphism

2003-07-02 Thread Joe Conway
Tom Lane wrote:
Ugh.  That seems like a really crude way to handle things.  In the first
place, a variable adds overhead whether you need it or not; in the
second place, what's the value of the variable if I try to fetch it,
or the effects if I assign to it?  $0 seems like a rather
randomly-chosen notation.
Well, not exactly random. In plpgsql the arguments are created inside 
the function body as $1, $2, etc., so $0 seemed reasonable for the 
return type variable. It was also very non-intrusive, since the lexer 
already was set up to recognize \${digit}+, and $0 was going unused.

Overhead is only added to functions returning polymorphic. All others 
incur no overhead, except bypassing an if(){code-block}.

If you try to fetch the variable, it will be NULL. I don't think you can 
assign to it any more than you can $1,$2, etc for the arguments (but 
I'll check that out).

I'm wondering whether we couldn't invent some notation along the lines
of "%rettype" to handle this issue.  (But the other %foo notations in
plpgsql modify some argument, and I'm not sure what %rettype should
modify.)  Or perhaps "functionname%type", although that seems subtly
wrong for reasons I can't quite put my finger on at this late hour.
Anyway, I'd like a representation that doesn't involve a phony variable.
Any other implementation will be much more intrusive, involving the 
lexer and probably three new functions, ala plpgsql_parse_wordtype(), 
plpgsql_parse_dblwordtype(), and plpgsql_parse_tripwordtype() (or at 
least significant hacking on the three mentioned).

But if that's the way you prefer, I'll get on it :-)

Joe



---(end of broadcast)---
TIP 4: Don't 'kill -9' the postmaster


Re: [PATCHES] "fix" for plpgsql polymorphism

2003-07-02 Thread Alvaro Herrera
On Thu, Jul 03, 2003 at 12:11:36AM -0400, Tom Lane wrote:
> Joe Conway <[EMAIL PROTECTED]> writes:
> > Alvaro Herrera wrote:
> >> why is this a malloc() and not palloc()?  And when/where/how is it freed?
> 
> > It isn't, at least not until the backend exits ;-)
> 
> > This is how plpgsql is done throughout, pretty much. It's not so bad 
> > when you remember that plpgsql functions are "compiled" once, and then 
> > cached for future calls by the same backend.
> 
> I think palloc would actually be wrong there, because it would allocate
> memory that would go away soon (certainly not later than end of
> transaction) whereas the structure needs to live as long as the plpgsql
> function cache entry does.  Without a switch into a suitably-long-lived
> context, this code can't use palloc.

That'd be TopMemoryContext.  Not too much a win, I think.  Maybe each
plpgsql function should have it's own context, destroyed by CREATE OR
REPLACE FUNCTION, for example.

-- 
Alvaro Herrera ()
"I dream about dreams about dreams", sang the nightingale
under the pale moon (Sandman)

---(end of broadcast)---
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]


Re: [PATCHES] "fix" for plpgsql polymorphism

2003-07-02 Thread Tom Lane
Joe Conway <[EMAIL PROTECTED]> writes:
> Alvaro Herrera wrote:
>> why is this a malloc() and not palloc()?  And when/where/how is it freed?

> It isn't, at least not until the backend exits ;-)

> This is how plpgsql is done throughout, pretty much. It's not so bad 
> when you remember that plpgsql functions are "compiled" once, and then 
> cached for future calls by the same backend.

I think palloc would actually be wrong there, because it would allocate
memory that would go away soon (certainly not later than end of
transaction) whereas the structure needs to live as long as the plpgsql
function cache entry does.  Without a switch into a suitably-long-lived
context, this code can't use palloc.

> Having said that, however, I know Tom would like to see all of this 
> redone in the future, with palloc, and maybe a specific memory context 
> to ensure we don't leak memory when we don't want to.

Yah.

regards, tom lane

---(end of broadcast)---
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]


Re: [PATCHES] "fix" for plpgsql polymorphism

2003-07-02 Thread Tom Lane
Joe Conway <[EMAIL PROTECTED]> writes:
> Inside the the function body, you can access the actual function call
> time *argument* types to create local variables by using the %type
> construct, e.g.:
>  v_myvar $1%type;
> However, there is currently is *no way* to create a variable based on 
> the return type, severely limiting the utility of polymorphic plpgsql 
> functions.

Good point.  I agree this is worth addressing.

> So what does the attached patch do? It adds an additional variable to 
> any function with a polymorphic return type (only), called $0, which 
> represents the actual function call time return type.

Ugh.  That seems like a really crude way to handle things.  In the first
place, a variable adds overhead whether you need it or not; in the
second place, what's the value of the variable if I try to fetch it,
or the effects if I assign to it?  $0 seems like a rather
randomly-chosen notation.

I'm wondering whether we couldn't invent some notation along the lines
of "%rettype" to handle this issue.  (But the other %foo notations in
plpgsql modify some argument, and I'm not sure what %rettype should
modify.)  Or perhaps "functionname%type", although that seems subtly
wrong for reasons I can't quite put my finger on at this late hour.
Anyway, I'd like a representation that doesn't involve a phony variable.

regards, tom lane

---(end of broadcast)---
TIP 8: explain analyze is your friend


Re: [PATCHES] "fix" for plpgsql polymorphism

2003-07-02 Thread Joe Conway
Alvaro Herrera wrote:
why is this a malloc() and not palloc()?  And when/where/how is it freed?

It isn't, at least not until the backend exits ;-)

This is how plpgsql is done throughout, pretty much. It's not so bad 
when you remember that plpgsql functions are "compiled" once, and then 
cached for future calls by the same backend.

Having said that, however, I know Tom would like to see all of this 
redone in the future, with palloc, and maybe a specific memory context 
to ensure we don't leak memory when we don't want to.

Joe

---(end of broadcast)---
TIP 3: if posting/reading through Usenet, please send an appropriate
 subscribe-nomail command to [EMAIL PROTECTED] so that your
 message can get through to the mailing list cleanly


Re: [PATCHES] "fix" for plpgsql polymorphism

2003-07-02 Thread Alvaro Herrera
On Wed, Jul 02, 2003 at 07:31:28PM -0700, Joe Conway wrote:

I haven't looked at the plpgsql code so IMBFOS, but

> + /*
> +  * Normal return values get a var node
> +  */
> + var = malloc(sizeof(PLpgSQL_var));
> + memset(var, 0, sizeof(PLpgSQL_var));

why is this a malloc() and not palloc()?  And when/where/how is it freed?

-- 
Alvaro Herrera ()
"El Maquinismo fue proscrito so pena de cosquilleo hasta la muerte"
(Ijon Tichy en Viajes, Stanislaw Lem)

---(end of broadcast)---
TIP 4: Don't 'kill -9' the postmaster


Re: [PATCHES] "fix" for plpgsql polymorphism

2003-07-02 Thread Bruce Momjian

I think we should apply it.  This is cleanup time for patches already
applied too.

---

Joe Conway wrote:
> OK, so maybe it is a "hold for 7.5" item, but I think it could be argued 
> that it is a (relatively simple and safe) fix for a relatively big 
> deficiency with the recently committed plpgsql polymorphism.
> 
> By way of explanation, the new plpgsql polymorphism capability means 
> that a function can be declared like this:
> 
> CREATE OR REPLACE FUNCTION foo(anyelement) returns anyarray AS '
>  function body
> ' language 'plpgsql';
> 
> The argument and return type are determined at function call time, and
> in this example the return type is constrained to be an array of the
> argument type.
> 
> Inside the the function body, you can access the actual function call
> time *argument* types to create local variables by using the %type
> construct, e.g.:
> 
>  v_myvar $1%type;
> 
> However, there is currently is *no way* to create a variable based on 
> the return type, severely limiting the utility of polymorphic plpgsql 
> functions. Because the polymorphic plpgsql patch was submitted just 
> before the freeze (a few hours), I didn't have enough experience 
> actually trying to write useful polymorphic plpgsql functions to know 
> this would be a deficiency.
> 
> So what does the attached patch do? It adds an additional variable to 
> any function with a polymorphic return type (only), called $0, which 
> represents the actual function call time return type. With $0 defined, 
> now you can declare a local variable inside the function body using 
> $0%type (it isn't useful for anything else, and is set to NULL for good 
> measure). For example:
> 
> create or replace function greatest(anyarray)
> returns anyelement as '
> declare
> v_arr alias for $1;
> v_lb int;
> v_ub int;
> v_greatest $0%type;
> begin
> v_lb := array_lower(v_arr,1);
> v_ub := array_upper(v_arr,1);
> v_greatest := v_arr[v_lb];
> for i in v_lb + 1 .. v_ub loop
>   if v_arr[i] > v_greatest then
> v_greatest := v_arr[i];
>   end if;
> end loop;
> return v_greatest;
> end;
> ' language 'plpgsql';
> 
> create table g(f1 text, f2 text, f3 text, f4 text, f5 text, f6 text);
> insert into g values ('a','b','c','d','e','f');
> insert into g values ('z','x','c','v','b','n');
> create table h(f1 int, f2 int, f3 int);
> insert into h values (42,6,39);
> insert into h values (2,3,4);
> 
> regression=# select greatest(array[f1,f2]) from g;
> greatest
> --
> b
> z
> (2 rows)
> 
> regression=# select greatest(array[f1,f2,f3,f4,f5,f6]) from g;
> greatest
> --
> f
> z
> (2 rows)
> 
> regression=# select greatest(array[f1,f2]) from h;
> greatest
> --
>   42
>3
> (2 rows)
> 
> regression=# select greatest(array[f1,f2,f3]) from h;
> greatest
> --
>   42
>4
> (2 rows)
> 
> The entire patch is less than 60 lines, and it is completely localized 
> to the polymorphic return value case. If accepted, I will of course 
> follow with the needed documentation (none of the polymorphic stuff is 
> documented yet anyway).
> 
> The $0 variable could be extended later to the same functionality for a 
> plpgsql function returning record, but I wanted to keep the patch 
> focused so that it might be allowed into 7.4 as a "fix".
> 
> If there are no objections, please apply. Otherwise please hold for 7.5.
> 
> Thanks,
> 
> Joe
> 

> Index: src/pl/plpgsql/src/pl_comp.c
> ===
> RCS file: /opt/src/cvs/pgsql-server/src/pl/plpgsql/src/pl_comp.c,v
> retrieving revision 1.59
> diff -c -r1.59 pl_comp.c
> *** src/pl/plpgsql/src/pl_comp.c  1 Jul 2003 21:47:09 -   1.59
> --- src/pl/plpgsql/src/pl_comp.c  3 Jul 2003 02:13:59 -
> ***
> *** 354,359 
> --- 354,395 
>   function->fn_rettyplen = typeStruct->typlen;
>   function->fn_rettypelem = typeStruct->typelem;
>   perm_fmgr_info(typeStruct->typinput, 
> &(function->fn_retinput));
> + 
> + /*
> +  * install $0 reference, but only for polymorphic
> +  * return types
> +  */
> + if (procStruct->prorettype == ANYARRAYOID ||
> + procStruct->prorettype == ANYELEMENTOID)
> + {
> + charbuf[32];
> + 
> + /* name for variable */
> + snprintf(buf, sizeof(buf), "$%d", 0);
> + 
> + /*
> +  * Normal return values get a var node
> +