Description:
Hi there,
there is a major bug with UDFs. I developed a simple UDF function in C and when I call it from mysql console I got the parameters. Function takes 2 parameters however I can never get the length of the 2nd parameter (args->lengths[1]) correct eventhough the value is correct. However when I passed 3 parameters the args->lengths[1] gives me the third parameter value. So I can't get the 2nd parameter length.
For example;
my function is demonstrated below
SELECT SIMIL("a", "a", "abc") FROM dual;
and I get the following values in C code
args->args[0] => correct
args->args[1] => correct
args->args[2] => correct
args->lengths[0] => correct
args->lengths[1] => nothing
args->lengths[2] => 2nd parameter length
Here is my code as well
DLL_EXPORT my_bool SIMIL_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
//if (args->arg_count != 2)
//{
//Requires more argument for instance
//x_strlcpy(message, "No arguments allowed (udf: lib_mysqludf_str_info)", MYSQL_ERRMSG_SIZE);
// return 1;
//}
if (args->arg_type[0] != STRING_RESULT)
return 1;
if (args->arg_type[1] != STRING_RESULT)
return 1;
initid->maybe_null = 1;
initid->max_length = 255+1;//20;//(4) - 1;
//initid->const_item = 0;//1 if the result same for each calls
return 0;
}
DLL_EXPORT void SIMIL_deinit(UDF_INIT *initid ATTRIBUTE_UNUSED)
{
}
DLL_EXPORT char* SIMIL( UDF_INIT *initid,
UDF_ARGS *args,
char *result,
unsigned long *res_length,
char *null_value,
char *error)
{
//memcpy(result, args->args[0], args->lengths[0]);
unsigned long iStrLen0 = args->lengths[0];
unsigned long iStrLen1 = args->lengths[1];
unsigned long iStrLen2 = 0;
if (args->arg_count>2)
{
iStrLen2 = args->lengths[2];
}
//char sTest = 0x30 + iStrLen0;
//int len = 6;
int len0 = (int)iStrLen0;
int len1 = (int)iStrLen1;
int len2 = (int)iStrLen2;
if (len0>=255)
len0=255;
//if (len1>=255)
// len1=strlen(args->lengths[1]);
char word0[255]="";
char word1[255]="";
//memcpy(word0, args->args[1], len1);
//memcpy(word1, args->args[1], len1);
int index=0;
result[index++] = 0x30 + args->arg_count;
result[index++] = 0x30 + len0;
result[index++] = 0x30 + len1;
result[index++] = 0x30 + len2;
memcpy(result+index, args->args[1], 4);
//memcpy(result, word1, len1);
*res_length = 6;
return result;
}
How to repeat:
For example;
my function is demonstrated below
SELECT SIMIL("a", "a", "abc") FROM dual;
and I get the following values in C code
args->args[0] => correct
args->args[1] => correct
args->args[2] => correct
args->lengths[0] => correct
args->lengths[1] => nothing
args->lengths[2] => 2nd parameter length
Here is my code as well
DLL_EXPORT my_bool SIMIL_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
//if (args->arg_count != 2)
//{
//Requires more argument for instance
//x_strlcpy(message, "No arguments allowed (udf: lib_mysqludf_str_info)", MYSQL_ERRMSG_SIZE);
// return 1;
//}
if (args->arg_type[0] != STRING_RESULT)
return 1;
if (args->arg_type[1] != STRING_RESULT)
return 1;
initid->maybe_null = 1;
initid->max_length = 255+1;//20;//(4) - 1;
//initid->const_item = 0;//1 if the result same for each calls
return 0;
}
DLL_EXPORT void SIMIL_deinit(UDF_INIT *initid ATTRIBUTE_UNUSED)
{
}
DLL_EXPORT char* SIMIL( UDF_INIT *initid,
UDF_ARGS *args,
char *result,
unsigned long *res_length,
char *null_value,
char *error)
{
//memcpy(result, args->args[0], args->lengths[0]);
unsigned long iStrLen0 = args->lengths[0];
unsigned long iStrLen1 = args->lengths[1];
unsigned long iStrLen2 = 0;
if (args->arg_count>2)
{
iStrLen2 = args->lengths[2];
}
//char sTest = 0x30 + iStrLen0;
//int len = 6;
int len0 = (int)iStrLen0;
int len1 = (int)iStrLen1;
int len2 = (int)iStrLen2;
if (len0>=255)
len0=255;
//if (len1>=255)
// len1=strlen(args->lengths[1]);
char word0[255]="";
char word1[255]="";
//memcpy(word0, args->args[1], len1);
//memcpy(word1, args->args[1], len1);
int index=0;
result[index++] = 0x30 + args->arg_count;
result[index++] = 0x30 + len0;
result[index++] = 0x30 + len1;
result[index++] = 0x30 + len2;
memcpy(result+index, args->args[1], 4);
//memcpy(result, word1, len1);
*res_length = 6;
return result;
}
Description: Hi there, there is a major bug with UDFs. I developed a simple UDF function in C and when I call it from mysql console I got the parameters. Function takes 2 parameters however I can never get the length of the 2nd parameter (args->lengths[1]) correct eventhough the value is correct. However when I passed 3 parameters the args->lengths[1] gives me the third parameter value. So I can't get the 2nd parameter length. For example; my function is demonstrated below SELECT SIMIL("a", "a", "abc") FROM dual; and I get the following values in C code args->args[0] => correct args->args[1] => correct args->args[2] => correct args->lengths[0] => correct args->lengths[1] => nothing args->lengths[2] => 2nd parameter length Here is my code as well DLL_EXPORT my_bool SIMIL_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { //if (args->arg_count != 2) //{ //Requires more argument for instance //x_strlcpy(message, "No arguments allowed (udf: lib_mysqludf_str_info)", MYSQL_ERRMSG_SIZE); // return 1; //} if (args->arg_type[0] != STRING_RESULT) return 1; if (args->arg_type[1] != STRING_RESULT) return 1; initid->maybe_null = 1; initid->max_length = 255+1;//20;//(4) - 1; //initid->const_item = 0;//1 if the result same for each calls return 0; } DLL_EXPORT void SIMIL_deinit(UDF_INIT *initid ATTRIBUTE_UNUSED) { } DLL_EXPORT char* SIMIL( UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *null_value, char *error) { //memcpy(result, args->args[0], args->lengths[0]); unsigned long iStrLen0 = args->lengths[0]; unsigned long iStrLen1 = args->lengths[1]; unsigned long iStrLen2 = 0; if (args->arg_count>2) { iStrLen2 = args->lengths[2]; } //char sTest = 0x30 + iStrLen0; //int len = 6; int len0 = (int)iStrLen0; int len1 = (int)iStrLen1; int len2 = (int)iStrLen2; if (len0>=255) len0=255; //if (len1>=255) // len1=strlen(args->lengths[1]); char word0[255]=""; char word1[255]=""; //memcpy(word0, args->args[1], len1); //memcpy(word1, args->args[1], len1); int index=0; result[index++] = 0x30 + args->arg_count; result[index++] = 0x30 + len0; result[index++] = 0x30 + len1; result[index++] = 0x30 + len2; memcpy(result+index, args->args[1], 4); //memcpy(result, word1, len1); *res_length = 6; return result; } How to repeat: For example; my function is demonstrated below SELECT SIMIL("a", "a", "abc") FROM dual; and I get the following values in C code args->args[0] => correct args->args[1] => correct args->args[2] => correct args->lengths[0] => correct args->lengths[1] => nothing args->lengths[2] => 2nd parameter length Here is my code as well DLL_EXPORT my_bool SIMIL_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { //if (args->arg_count != 2) //{ //Requires more argument for instance //x_strlcpy(message, "No arguments allowed (udf: lib_mysqludf_str_info)", MYSQL_ERRMSG_SIZE); // return 1; //} if (args->arg_type[0] != STRING_RESULT) return 1; if (args->arg_type[1] != STRING_RESULT) return 1; initid->maybe_null = 1; initid->max_length = 255+1;//20;//(4) - 1; //initid->const_item = 0;//1 if the result same for each calls return 0; } DLL_EXPORT void SIMIL_deinit(UDF_INIT *initid ATTRIBUTE_UNUSED) { } DLL_EXPORT char* SIMIL( UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *null_value, char *error) { //memcpy(result, args->args[0], args->lengths[0]); unsigned long iStrLen0 = args->lengths[0]; unsigned long iStrLen1 = args->lengths[1]; unsigned long iStrLen2 = 0; if (args->arg_count>2) { iStrLen2 = args->lengths[2]; } //char sTest = 0x30 + iStrLen0; //int len = 6; int len0 = (int)iStrLen0; int len1 = (int)iStrLen1; int len2 = (int)iStrLen2; if (len0>=255) len0=255; //if (len1>=255) // len1=strlen(args->lengths[1]); char word0[255]=""; char word1[255]=""; //memcpy(word0, args->args[1], len1); //memcpy(word1, args->args[1], len1); int index=0; result[index++] = 0x30 + args->arg_count; result[index++] = 0x30 + len0; result[index++] = 0x30 + len1; result[index++] = 0x30 + len2; memcpy(result+index, args->args[1], 4); //memcpy(result, word1, len1); *res_length = 6; return result; }