2 messages in com.mysql.lists.plusplusStrange return behaviour in UDF (bug?)
FromSent OnAttachments
Richard Massa24 May 2004 17:39 
Sinisa Milivojevic25 May 2004 06:28 
Subject:Strange return behaviour in UDF (bug?)
From:Richard Massa (rma@unixboxen.net)
Date:05/24/2004 05:39:12 PM
List:com.mysql.lists.plusplus

Hi there,

I'm getting a strange behaviour when returning a value from my user defined function. When I print the return value inside of the function, I get one answer (the correct one), however mysql reports a different value all together. Is this my programming error or a mysql bug?

Here's what I'm seeing:

In mysql:

+-------------------------------------------------------------------------+ | ddist(m.x, m.y, m.z, n.x, n.y, n.z, 30.0893021, 30.3757286, 32.6442299) | +-------------------------------------------------------------------------+ | 0.72 | | 0.66 | | 0.61 | | 0.47 | +-------------------------------------------------------------------------+

my hostname.err logfile where I print debugging info:

result: 33.048230 result: 9.203189 result: 12.836390 result: 9.615359

Here's the source code for my program

#include <stdio.h> #include <string.h> #include <my_global.h> #include <my_sys.h> #include <mysql.h> #include <m_ctype.h>

#ifdef HAVE_DLOPEN

extern "C" {

my_bool ddist_init (UDF_INIT *initid, UDF_ARGS *args, char *message); void ddist_deinit (UDF_INIT *initid); double ddist (UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);

}

void ddist_deinit(UDF_INIT *initid){}

my_bool ddist_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { initid->decimals=2; // We want 2 decimals in the result initid->max_length=6; // 3 digits + . + 2 decimals

return 0; /* int i=0; // counter

if (!args->arg_count || args->arg_count != 9) { strcpy(message,"dist must have exactly nine arguments"); return 2; }

for ( i=0;i<6;i++ ) { if ( args->arg_type[i] != REAL_RESULT ) strcpy( message, "dist must be passed six real numbers"); return 2; } */ }

double ddist(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { double xi, yi, zi, xj, yj, zj, cubex, cubey, cubez ; //variables for arguments int shiftx, shifty, shiftz; // temp variables double rijx, rijy, rijz; // temp variables double result; // result

xi = *((double*)args->args[0]); yi = *((double*)args->args[1]); zi = *((double*)args->args[2]); xj = *((double*)args->args[3]); yj = *((double*)args->args[4]); zj = *((double*)args->args[5]);

cubex = *((double*)args->args[6]); cubey = *((double*)args->args[7]); cubez = *((double*)args->args[8]);

shiftx = int( rint( (xi-xj)/cubex )); shifty = int( rint( (yi-yj)/cubey )); shiftz = int( rint( (zi-zj)/cubez )); fprintf(stderr,"sx=%d, sy=%d, sz=%d, cx=%f, cy=%f, cz=%f, xi=%f, yi=%f, zi=%f,
xj=%f, yj=%f,
zj=%f\n",shiftx,shifty,shiftz,cubex,cubey,cubez,xi,yi,zi,xj,yj,zj);

rijx = xi-xj-cubex*shiftx; rijy = yi-yi-cubey*shifty; rijz = zi-zj-cubez*shiftz; fprintf(stderr,"rijx=%f,rijy=%f,rijz=%f\n",rijx,rijy,rijz);

result = sqrt( (rijx*rijx) + (rijy*rijy) + (rijz*rijz) );

fprintf(stderr,"test: %f\n",(rijz*rijz)); fprintf(stderr,"result: %f\n",result); return result; }

#endif /* HAVE_DLOPEN */

Here's what I'm using to compile:

g++ -O3 -DDBUG_OFF -fno-implicit-templates -fno-exceptions -fno-rtti -shared -I/usr/include/mysql -rdynamic dist.cc -o dist.so

Anyone have any ideas?

Thanks, Richard