Unix Technical Forum

Function with record type as argument

This is a discussion on Function with record type as argument within the pgsql Novice forums, part of the PostgreSQL category; --> In a followup to an earlier question from today from another person, is it possible to create and use ...


Go Back   Unix Technical Forum > Database Server Software > PostgreSQL > pgsql Novice

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 04-17-2008, 08:31 PM
Sean Davis
 
Posts: n/a
Default Function with record type as argument

In a followup to an earlier question from today from another person, is
it possible to create and use a function that takes as input a generic
"record"? Specifically, how would I use a function like:

create or replace function perl_columns(record) returns text as $a$
my ($rec)=@_;
my $xml_ex = '';
foreach my $tag (keys %$rec) {
$xml_ex = "<$tag>" . $rec->{$tag} . "</$tag>\n";
}
return $xml_ex;
$a$ language plperlu;

Thanks,
Sean


---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faq

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 04-17-2008, 08:31 PM
Tom Lane
 
Posts: n/a
Default Re: Function with record type as argument

Sean Davis <sdavis2@mail.nih.gov> writes:
> In a followup to an earlier question from today from another person, is
> it possible to create and use a function that takes as input a generic
> "record"?


Not in any of the PL languages. I think you could do it in C.

regards, tom lane

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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 04-17-2008, 08:31 PM
Sean Davis
 
Posts: n/a
Default Re: Function with record type as argument

Tom,

Thanks for the reply. Just for fun, I did create the function in
pl/perlu without difficulty. However, I can't call it, as record types
do not seem to match any prototyping....

Sean

On Feb 22, 2005, at 10:20 AM, Tom Lane wrote:

> Sean Davis <sdavis2@mail.nih.gov> writes:
>> In a followup to an earlier question from today from another person,
>> is
>> it possible to create and use a function that takes as input a generic
>> "record"?

>
> Not in any of the PL languages. I think you could do it in C.
>
> regards, tom lane



---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 04-17-2008, 08:31 PM
Tom Lane
 
Posts: n/a
Default Re: Function with record type as argument

Sean Davis <sdavis2@mail.nih.gov> writes:
> Thanks for the reply. Just for fun, I did create the function in
> pl/perlu without difficulty. However, I can't call it, as record types
> do not seem to match any prototyping....


I don't think plperl has a validator function, so it's not going to
complain at CREATE FUNCTION time, but it definitely barfs at runtime:

/* Disallow pseudotype argument */
if (typeStruct->typtype == 'p')
{
free(prodesc->proname);
free(prodesc);
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("plperl functions cannot take type %s",
format_type_be(procStruct->proargtypes[i]))));
}

The point about what input will be considered to match type-wise is
another good one that I hadn't thought about. Looking at the source
code, it appears that 8.0 will consider an explicit ROW(...) construct
to match a RECORD argument, but not a named composite type (e.g.,
a row coming from a table) :-(. This is probably an oversight stemming
from the fact that no one's ever exercised the case.

I don't have plperl installed on this machine, but pltcl behaves about
the same:

regression=# create function f1(record) returns int as $$return 1$$ language pltcl;
CREATE FUNCTION
regression=# select f1(row(33,44));
ERROR: pltcl functions cannot take type record
regression=# select f1(i.*) from int8_tbl i;
ERROR: function f1(int8_tbl) does not exist

The first select is actually a "success", since control is getting as
far as letting pltcl decide it won't do it.

plpgsql probably isn't ever going to allow RECORD arguments, since it
likes to work with known types, but in principle I think the other PLs
could handle the case. They all are willing to take named composite
types and this doesn't seem much different for their purposes.

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 04-17-2008, 08:31 PM
Sean Davis
 
Posts: n/a
Default Re: Function with record type as argument


On Feb 22, 2005, at 11:03 AM, Tom Lane wrote:

> Sean Davis <sdavis2@mail.nih.gov> writes:
>> Thanks for the reply. Just for fun, I did create the function in
>> pl/perlu without difficulty. However, I can't call it, as record
>> types
>> do not seem to match any prototyping....

>
> I don't think plperl has a validator function, so it's not going to
> complain at CREATE FUNCTION time, but it definitely barfs at runtime:
>
> /* Disallow pseudotype argument */
> if (typeStruct->typtype == 'p')
> {
> free(prodesc->proname);
> free(prodesc);
> ereport(ERROR,
> (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
> errmsg("plperl functions cannot take type
> %s",
>
> format_type_be(procStruct->proargtypes[i]))));
> }
>
> The point about what input will be considered to match type-wise is
> another good one that I hadn't thought about. Looking at the source
> code, it appears that 8.0 will consider an explicit ROW(...) construct
> to match a RECORD argument, but not a named composite type (e.g.,
> a row coming from a table) :-(. This is probably an oversight stemming
> from the fact that no one's ever exercised the case.
>
> I don't have plperl installed on this machine, but pltcl behaves about
> the same:
>
> regression=# create function f1(record) returns int as $$return 1$$
> language pltcl;
> CREATE FUNCTION
> regression=# select f1(row(33,44));
> ERROR: pltcl functions cannot take type record
> regression=# select f1(i.*) from int8_tbl i;
> ERROR: function f1(int8_tbl) does not exist
>
> The first select is actually a "success", since control is getting as
> far as letting pltcl decide it won't do it.
>
> plpgsql probably isn't ever going to allow RECORD arguments, since it
> likes to work with known types, but in principle I think the other PLs
> could handle the case. They all are willing to take named composite
> types and this doesn't seem much different for their purposes.


Tom,

As usual, thanks for the enlightenment. Allowing generic record types
seems quite intuitive to a perl programmer and since perl is a very
"untyped" language, it seems quite practicable to allow? Of course, I
don't have the knowledge to "make it so".... It does seem that for
some applications, allowing pls other than pgsql to get access to
whatever is passed (a generic record type) would be a useful extension.

Sean


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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 12:01 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com