Thanks Mark, it worked. Also I used same function without BAT and it
calculates I think, not check the exact values yet.What will be the
improvement with using BATs?
On Wed, Mar 30, 2016 at 3:31 PM, Sjoerd Mullender
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
Take a look at the Mercurial repository [1] and especially the file reverse/README.rst in there. It contains a lot of hands-on information for creating a UDF.
[1] http://dev.monetdb.org/hg/MonetDB-extend either point your browser here, or, better yet, clone it: hg clone http://dev.monetdb.org/hg/MonetDB-extend
On 30/03/16 14:59, Mark Raasveldt wrote:
Hey Shmagi,
You are not using the correct function signature for writing a MonetDB UDF. The correct function signature is first the return value as pointer (this is where you write the return value to), and then a list of all the input parameters as pointers. For your function, the correct function signature is:
str UDFbitand(flt *ret, lng *a, lng *b);
Where (a,b) are the input parameters, and (ret) is where you write the return value. The actual return value of the function is a string that is either MAL_SUCCEED (if the function has completed correctly), or an error message (if it has not).
I notice in your function that in the end you write the result to a local variable:
float final = count/(float)length;
This variable is not exported from the function, and as such cannot be read by the database. Instead, the return value of the function should be written to the "ret" pointer, as such:
*ret = count / (float) length;
Also, always initialize your variables if you expect them to have a specific value. In your code, you have the following variables.
int length; int count;
Which you then increment. As these variables are uninitialized, their value is undefined. Some compilers may set their value to 0, but you should not rely on this.
I have rewritten your UDF to operate correctly, here's the code.
str UDFbitand(flt *ret, lng *a, lng *b) { long long int temp = weirdAnd(*a, *b); long long int temp2 = weirdAnd(*a, *b); int length = 0; int count = 0;
while (temp != 0) { temp/=10; length++; }
while (temp2 != 0) { if (temp2 % 10 == 1) count++; temp2 /= 10; }
*ret = count/(float)length; return MAL_SUCCEED; }
This gives me the following result.
sql>SELECT bitand(1111, 1010); +---------------------+ | bitand_single_value | +=====================+ | 0.5 | +---------------------+
Note that this is a single scalar UDF. While you can use this UDF to operate on entire columns, if you want the UDF to perform well you should implement a batch UDF that operates on BATs directly.
Hope that helps,
Mark
----- Original Message ----- From: "Shmagi Kavtaradze"
To: "users-list" Sent: Wednesday, March 30, 2016 2:31:18 PM Subject: UDF returning 0 as a result I wrote a function bitand. When I do "select bitand(1111,1010);" it gives "0" instead of "0.5". My function:
--UDF.c--
str UDFbitand(long long int a, long long b) { long long int weirdAnd(unsigned int a, unsigned int b) { long long int result = 0; int coef = 1; while (a || b) { result += ((a % 10) && (b % 10)) * coef; coef *= 10; a /= 10; b /= 10; } return result; }
long long int temp = weirdAnd(a, b); long long int temp2 = weirdAnd(a, b); int length; int count;
while (temp != 0) { temp/=10; length++; }
while (temp2 != 0) { if (temp2 % 10 == 1) count++; temp2 /= 10; }
float final = count/(float)length; return MAL_SUCCEED; }
--UDF.mal--
command bitand(a:lng,b:lng):flt address UDFbitand comment "bitand";
--80_UDF.sql--
create function bitand(a BIGINT,b BIGINT) returns REAL external name udf.bitand;
When I test my C code in netbeans it works as supposed. Any ideas? Thanks in advance.
_______________________________________________ users-list mailing list users-list@monetdb.org https://www.monetdb.org/mailman/listinfo/users-list _______________________________________________ users-list mailing list users-list@monetdb.org https://www.monetdb.org/mailman/listinfo/users-list
- -- Sjoerd Mullender -----BEGIN PGP SIGNATURE----- Version: GnuPG v2
iQEcBAEBCAAGBQJW+9VBAAoJEISMxT6LrWYgS70H/ijlGSj8hxwBTMgaRFYwtrqP WTXwYLJMbMMSRhaMDLL6mmPJ8raKnkHkXMeVNr89gTvgRJbdrEmZ822VBXAGCgqw vMhB7R2v2GjlKZKaDQzeYnZoN+pFpKSDAlE/Ja+9ufdUyPK0NO79z+/HaeGP5pPt cDvtCwRPw3my7JBE95eRnBchKyK/89FT/zWI1Fuj+dVHUSDBP+Gu91uZetT0VK0L x4S/jmKYhntQcNfeZLLD69pGmVsVL/l30E2JEKXV4oUB/qTr4C+Gm7upSUqyGUZz esY+pV0XPXkkf6FQ1I1Jv5oY+CjJpVOcYw8YyXqszZ6UBBiCxEXsEoVl9fqJHKc= =PfPr -----END PGP SIGNATURE----- _______________________________________________ users-list mailing list users-list@monetdb.org https://www.monetdb.org/mailman/listinfo/users-list