Обсуждение: c language functions

Поиск
Список
Период
Сортировка

c language functions

От
Rodrigo Barboza
Дата:
<div dir="ltr">Hello.<div style="style">I'm trying to create a generic add function.</div><div style="style">I have
defineda type my_uint and it needs a '+' operator.</div><div style="style">This operator should work like normal int +
intoperation.</div><div style="style">The function is defined expecting arguments (my_uint, anyelement).</div><div
style="style"><br/></div><div style="style">I'm confused in retrieving the anyelement type, value and than do the add
operationand return the correct value and type.</div><div style="style">I tried to use PG_GETARG_DATUM, but I don't
knowhow to extract the value from it (should it be a uint32, uint64, float or double).</div><div style="style"><br
/></div><divstyle="style">Any tips?</div><div style="style"><br /></div><div style="style"><br /></div></div> 

Re: c language functions

От
Robert Haas
Дата:
On Wed, Apr 3, 2013 at 11:26 AM, Rodrigo Barboza
<rodrigombufrj@gmail.com> wrote:
> Hello.
> I'm trying to create a generic add function.
> I have defined a type my_uint and it needs a '+' operator.
> This operator should work like normal int + int operation.
> The function is defined expecting arguments (my_uint, anyelement).
>
> I'm confused in retrieving the anyelement type, value and than do the add
> operation and return the correct value and type.
> I tried to use PG_GETARG_DATUM, but I don't know how to extract the value
> from it (should it be a uint32, uint64, float or double).
>
> Any tips?

Well, the information the function ends up receiving is going to
depend on how the function is declared at an SQL level.  So if you are
defining the function to take an argument of anyelement (which seems
unlikely to be a useful thing to do, but let's suppose you do it
anyway) then look at the C code for some other function that takes an
anyelement argument and look at how that function unpacks it.

Similarly, if you declare the function to take int4 argument, then go
look at the C code function that takes an int4 argument and see what
it does to unpack it.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: c language functions

От
Rodrigo Barboza
Дата:
<div dir="ltr">Why not useful?<div style="style">If I don't make it receive anyelement, I will have to create an add
functionfor each type.</div><div style="style">Correct me if I'm wrong.</div></div><div class="gmail_extra"><br /><br
/><divclass="gmail_quote">On Wed, Apr 3, 2013 at 2:27 PM, Robert Haas <span dir="ltr"><<a
href="mailto:robertmhaas@gmail.com"target="_blank">robertmhaas@gmail.com</a>></span> wrote:<br /><blockquote
class="gmail_quote"style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div
class="h5">OnWed, Apr 3, 2013 at 11:26 AM, Rodrigo Barboza<br /> <<a
href="mailto:rodrigombufrj@gmail.com">rodrigombufrj@gmail.com</a>>wrote:<br /> > Hello.<br /> > I'm trying to
createa generic add function.<br /> > I have defined a type my_uint and it needs a '+' operator.<br /> > This
operatorshould work like normal int + int operation.<br /> > The function is defined expecting arguments (my_uint,
anyelement).<br/> ><br /> > I'm confused in retrieving the anyelement type, value and than do the add<br /> >
operationand return the correct value and type.<br /> > I tried to use PG_GETARG_DATUM, but I don't know how to
extractthe value<br /> > from it (should it be a uint32, uint64, float or double).<br /> ><br /> > Any
tips?<br/><br /></div></div>Well, the information the function ends up receiving is going to<br /> depend on how the
functionis declared at an SQL level.  So if you are<br /> defining the function to take an argument of anyelement
(whichseems<br /> unlikely to be a useful thing to do, but let's suppose you do it<br /> anyway) then look at the C
codefor some other function that takes an<br /> anyelement argument and look at how that function unpacks it.<br /><br
/>Similarly, if you declare the function to take int4 argument, then go<br /> look at the C code function that takes an
int4argument and see what<br /> it does to unpack it.<br /><br /> --<br /> Robert Haas<br /> EnterpriseDB: <a
href="http://www.enterprisedb.com"target="_blank">http://www.enterprisedb.com</a><br /> The Enterprise PostgreSQL
Company<br/></blockquote></div><br /></div> 

Re: c language functions

От
Tom Lane
Дата:
Rodrigo Barboza <rodrigombufrj@gmail.com> writes:
> Why not useful?
> If I don't make it receive anyelement, I will have to create an add
> function for each type.

If you make it anyelement, then you're contracting to be able to add
any datatype whatsoever to a my_uint.  This is nonsensical.

You'd be better off declaring several specific addition functions,
one for each other type.  This will be an order of magnitude easier
to write, and probably run an order of magnitude faster too, because
just checking to see what type you got would already be significantly
more expensive than adding a couple of integers ought to be.

Look at the built-in types and functions for precedent.  There are
indeed separate functions for int2 + int2, int2 + int4, int4 + int2,
int4 + int4, etc etc.  If we were starting from scratch, we might reduce
that to just int4 + int4 and rely on the implicit coercion from int2 to
int4 to handle the other cases; but there's no way we'd put in run-time
type determination.
        regards, tom lane



Re: c language functions

От
Rodrigo Barboza
Дата:
<div dir="ltr">Well, I was checking inside my function the type of the second argument and switching between the
allowedtypes.<div style="style">This way kind of does the same thing of many functions, doesn't it?</div></div><div
class="gmail_extra"><br/><br /><div class="gmail_quote">On Wed, Apr 3, 2013 at 3:39 PM, Tom Lane <span dir="ltr"><<a
href="mailto:tgl@sss.pgh.pa.us"target="_blank">tgl@sss.pgh.pa.us</a>></span> wrote:<br /><blockquote
class="gmail_quote"style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">Rodrigo
Barboza<<a href="mailto:rodrigombufrj@gmail.com">rodrigombufrj@gmail.com</a>> writes:<br /> > Why not
useful?<br/> > If I don't make it receive anyelement, I will have to create an add<br /> > function for each
type.<br/><br /></div>If you make it anyelement, then you're contracting to be able to add<br /> any datatype
whatsoeverto a my_uint.  This is nonsensical.<br /><br /> You'd be better off declaring several specific addition
functions,<br/> one for each other type.  This will be an order of magnitude easier<br /> to write, and probably run an
orderof magnitude faster too, because<br /> just checking to see what type you got would already be significantly<br />
moreexpensive than adding a couple of integers ought to be.<br /><br /> Look at the built-in types and functions for
precedent. There are<br /> indeed separate functions for int2 + int2, int2 + int4, int4 + int2,<br /> int4 + int4, etc
etc. If we were starting from scratch, we might reduce<br /> that to just int4 + int4 and rely on the implicit coercion
fromint2 to<br /> int4 to handle the other cases; but there's no way we'd put in run-time<br /> type determination.<br
/><br/>                         regards, tom lane<br /></blockquote></div><br /></div> 

Re: c language functions

От
Robert Haas
Дата:
On Wed, Apr 3, 2013 at 3:25 PM, Rodrigo Barboza <rodrigombufrj@gmail.com> wrote:
> Well, I was checking inside my function the type of the second argument and
> switching between the allowed types.
> This way kind of does the same thing of many functions, doesn't it?

Sure, except that it will also call your function when someone does
my_int + text or my_int + bytea or my_int + box, which are surely a
lot less sensible.  It's probably a good idea to assume that if you
make your type work like the existing types, it's more likely to end
well than if you make it behave completely differently.

...Robert



Re: c language functions

От
Rodrigo Barboza
Дата:
<div dir="ltr">I see, that's true.<div style="style">I'm returning unknown type, there is a little more overhead. But
it'sworking now. =]</div><div style="style">Thanks for the help guys!</div></div><div class="gmail_extra"><br /><br
/><divclass="gmail_quote">On Wed, Apr 3, 2013 at 6:17 PM, Robert Haas <span dir="ltr"><<a
href="mailto:robertmhaas@gmail.com"target="_blank">robertmhaas@gmail.com</a>></span> wrote:<br /><blockquote
class="gmail_quote"style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Wed, Apr 3,
2013at 3:25 PM, Rodrigo Barboza <<a href="mailto:rodrigombufrj@gmail.com">rodrigombufrj@gmail.com</a>> wrote:<br
/>> Well, I was checking inside my function the type of the second argument and<br /> > switching between the
allowedtypes.<br /> > This way kind of does the same thing of many functions, doesn't it?<br /><br /></div>Sure,
exceptthat it will also call your function when someone does<br /> my_int + text or my_int + bytea or my_int + box,
whichare surely a<br /> lot less sensible.  It's probably a good idea to assume that if you<br /> make your type work
likethe existing types, it's more likely to end<br /> well than if you make it behave completely differently.<br
/><spanclass="HOEnZb"><font color="#888888"><br /> ...Robert<br /></font></span></blockquote></div><br /></div>