Обсуждение: c language functions
<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>
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
<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>
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
<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>
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
<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>