尝试在 mysql 中添加 udf 给出错误 ERROR 1127 (HY000): Can't find symbol in library
trying to add udf in mysql gives error ERROR 1127 (HY000): Can't find symbol in library
我一直在尝试在 mysql 5.6 中添加用户定义的函数,它执行一个简单的任务 - 即找到 column1 的最大值和 return 另一列的值,即 column2 对应于column1 的最大值。
我知道这个概念中有一些注意事项,比如如果 column1 有 2 个最大值,那么 column2 的哪个对应值应该 returned。不过这些都不是我现在主要关注的领域。
我已经编写了 column1 和 column2 都是双精度函数的程序。是运行。但是当我尝试 column1 是 double 而 column2 是 string.The 类型的情况时,我面临的问题是它给出了错误 ERROR 1127 (HY000): Can't find symbol 'strvalformax' in library
。这是我的 complete code
#ifdef STANDARD
#include <stdio.h>
#include <string.h>
#ifdef __WIN__
typedef unsigned __int64 ulonglong;
typedef __int64 longlong;
#else
typedef unsigned long long ulonglong;
typedef long long longlong;
#endif /*__WIN__*/
#else
#include <my_global.h>
#include <my_sys.h>
#endif
#include <mysql.h>
#include <m_ctype.h>
#include <m_string.h>
#ifdef HAVE_DLOPEN
extern "C" {
my_bool strvalformax_init( UDF_INIT* initid, UDF_ARGS* args, char* message );
void strvalformax_deinit( UDF_INIT* initid );
void strvalformax_clear(UDF_INIT *initid, char *is_null, char *is_error);
void strvalformax_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
void strvalformax_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
char* strvalformax( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
}
struct max_data
{
double max;
char* colval;
};
my_bool strvalformax_init( UDF_INIT* initid, UDF_ARGS* args, char* message )
{
if (args->arg_count != 2)
{
strcpy(message,"wrong number of arguments: strvalformax() requires two arguments");
return 1;
}
if (args->arg_type[1]!=STRING_RESULT)
{
strcpy(message,"correlation() requires a string as parameter 2");
return 1;
}
max_data *buffer = new max_data;
buffer->max = NULL;
buffer->colval= NULL;
initid->ptr = (char*)buffer;
return 0;
}
void strvalformax_deinit( UDF_INIT* initid )
{
max_data *buffer = (max_data*)initid->ptr;
if(buffer->colval!=NULL){
free(buffer->colval);
buffer->colval=NULL;
}
delete initid->ptr;
}
void strvalformax_clear(UDF_INIT *initid, char *is_null, char *is_error)
{
max_data *buffer = (max_data*)initid->ptr;
*is_null = 0;
*is_error = 0;
buffer->max=NULL;
buffer->colval=NULL;
}
void strvalformax_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* is_error )
{
strvalformax_clear(initid, is_null, is_error);
strvalformax_add( initid, args, is_null, is_error );
}
void strvalformax_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* is_error )
{
max_data *buffer = (max_data*)initid->ptr;
if (args->args[0]!=NULL && args->args[1]!=NULL)
{
if(buffer->max==NULL){
buffer->max = *(double*)args->args[0];
if(buffer->colval!=NULL){
free(buffer->colval);
buffer->colval=NULL;
}
buffer->colval = (char *)malloc(args->attribute_lengths[1]+1);
strcpy(buffer->colval,args->args[1],attribute_lengths[1]);
}else{
if((*(double*)args->args[0])>(buffer->max)){
buffer->max = *(double *)args->args[0];
if(buffer->colval!=NULL){
free(buffer->colval);
buffer->colval=NULL;
}
buffer->colval = (char *)malloc(args->attribute_lengths[1]+1);
strcpy(buffer->colval,args->args[1]);
}
}
}
}
char *strvalformax ( UDF_INIT* initid, UDF_ARGS* args,char* result,unsigned long* res_length, char* is_null, char* is_error )
{
max_data* buffer = (max_data*)initid->ptr;
result = buffer->colval;
*res_length = strlen(buffer->colval);
return result;
}
#endif
用于编译和link的命令
g++ -o udf_strvalformax.o -O2 -fPIC -I/usr/src/mariadb-5.5.30/include/ -I/usr/include/mysql -DHAVE_DLOPEN=1 -DMYSQL_DYNAMIC_PLUGIN -c udf_strvalformax.cc
用于link共享库的命令
ld -shared -o udf_strvalformax.so udf_strvalformax.o
已将共享对象文件复制到 mysql 插件库
cp udf_strvalformax.so /usr/lib/mysql/plugin/
终于调用了创建函数
CREATE AGGREGATE FUNCTION strvalformax RETURNS STRING SONAME 'udf_strvalformax.so';
它给出了错误
ERROR 1127 (HY000): Can't find symbol 'strvalformax' in library
我还检查了共享对象文件以查看符号是否可用以及它是否可用。这是 nm -gC --demangle udf_strvalformax.so
的结果
0000000000200a50 D __bss_start
0000000000200a50 D _edata
0000000000200a50 D _end
U free
U malloc
U strcpy
U strlen
00000000000006c0 T strvalformax_add
00000000000006a0 T strvalformax_clear
0000000000000660 T strvalformax_deinit
0000000000000540 T strvalformax_init
0000000000000760 T strvalformax_reset
00000000000007a0 T strvalformax(st_udf_init*, st_udf_args*, char*, unsigned long*, char*, char*)
U operator delete(void*)
U operator new(unsigned long)
我已经尝试找出问题 1.5 天了,但没有 progress.May 因为我提前遗漏了一些东西 here.thanks。
I also checked in the shared object file to see if symbol is available
or not and it is available.
不,它不在那里。 .so 包含一个损坏的符号
00000000000007a0 T strvalformax(st_udf_init*, st_udf_args*, char*, unsigned long*, char*, char*)
服务器只查找 strvalformax
。
使用普通的
nm udf_strvalformax.so
看看区别。
问题是使用 extern "C"
的声明
char* strvalformax( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
以及函数的实现
char *strvalformax ( UDF_INIT* initid, UDF_ARGS* args,char* result,unsigned long* res_length, char* is_null, char* is_error )
使用了不同的原型,所以它们不是同一个函数。
尝试使用准确的函数原型声明 extern C
(缺少参数 result
和 res_length
)。
我一直在尝试在 mysql 5.6 中添加用户定义的函数,它执行一个简单的任务 - 即找到 column1 的最大值和 return 另一列的值,即 column2 对应于column1 的最大值。
我知道这个概念中有一些注意事项,比如如果 column1 有 2 个最大值,那么 column2 的哪个对应值应该 returned。不过这些都不是我现在主要关注的领域。
我已经编写了 column1 和 column2 都是双精度函数的程序。是运行。但是当我尝试 column1 是 double 而 column2 是 string.The 类型的情况时,我面临的问题是它给出了错误 ERROR 1127 (HY000): Can't find symbol 'strvalformax' in library
。这是我的 complete code
#ifdef STANDARD
#include <stdio.h>
#include <string.h>
#ifdef __WIN__
typedef unsigned __int64 ulonglong;
typedef __int64 longlong;
#else
typedef unsigned long long ulonglong;
typedef long long longlong;
#endif /*__WIN__*/
#else
#include <my_global.h>
#include <my_sys.h>
#endif
#include <mysql.h>
#include <m_ctype.h>
#include <m_string.h>
#ifdef HAVE_DLOPEN
extern "C" {
my_bool strvalformax_init( UDF_INIT* initid, UDF_ARGS* args, char* message );
void strvalformax_deinit( UDF_INIT* initid );
void strvalformax_clear(UDF_INIT *initid, char *is_null, char *is_error);
void strvalformax_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
void strvalformax_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
char* strvalformax( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
}
struct max_data
{
double max;
char* colval;
};
my_bool strvalformax_init( UDF_INIT* initid, UDF_ARGS* args, char* message )
{
if (args->arg_count != 2)
{
strcpy(message,"wrong number of arguments: strvalformax() requires two arguments");
return 1;
}
if (args->arg_type[1]!=STRING_RESULT)
{
strcpy(message,"correlation() requires a string as parameter 2");
return 1;
}
max_data *buffer = new max_data;
buffer->max = NULL;
buffer->colval= NULL;
initid->ptr = (char*)buffer;
return 0;
}
void strvalformax_deinit( UDF_INIT* initid )
{
max_data *buffer = (max_data*)initid->ptr;
if(buffer->colval!=NULL){
free(buffer->colval);
buffer->colval=NULL;
}
delete initid->ptr;
}
void strvalformax_clear(UDF_INIT *initid, char *is_null, char *is_error)
{
max_data *buffer = (max_data*)initid->ptr;
*is_null = 0;
*is_error = 0;
buffer->max=NULL;
buffer->colval=NULL;
}
void strvalformax_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* is_error )
{
strvalformax_clear(initid, is_null, is_error);
strvalformax_add( initid, args, is_null, is_error );
}
void strvalformax_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* is_error )
{
max_data *buffer = (max_data*)initid->ptr;
if (args->args[0]!=NULL && args->args[1]!=NULL)
{
if(buffer->max==NULL){
buffer->max = *(double*)args->args[0];
if(buffer->colval!=NULL){
free(buffer->colval);
buffer->colval=NULL;
}
buffer->colval = (char *)malloc(args->attribute_lengths[1]+1);
strcpy(buffer->colval,args->args[1],attribute_lengths[1]);
}else{
if((*(double*)args->args[0])>(buffer->max)){
buffer->max = *(double *)args->args[0];
if(buffer->colval!=NULL){
free(buffer->colval);
buffer->colval=NULL;
}
buffer->colval = (char *)malloc(args->attribute_lengths[1]+1);
strcpy(buffer->colval,args->args[1]);
}
}
}
}
char *strvalformax ( UDF_INIT* initid, UDF_ARGS* args,char* result,unsigned long* res_length, char* is_null, char* is_error )
{
max_data* buffer = (max_data*)initid->ptr;
result = buffer->colval;
*res_length = strlen(buffer->colval);
return result;
}
#endif
用于编译和link的命令
g++ -o udf_strvalformax.o -O2 -fPIC -I/usr/src/mariadb-5.5.30/include/ -I/usr/include/mysql -DHAVE_DLOPEN=1 -DMYSQL_DYNAMIC_PLUGIN -c udf_strvalformax.cc
用于link共享库的命令
ld -shared -o udf_strvalformax.so udf_strvalformax.o
已将共享对象文件复制到 mysql 插件库
cp udf_strvalformax.so /usr/lib/mysql/plugin/
终于调用了创建函数
CREATE AGGREGATE FUNCTION strvalformax RETURNS STRING SONAME 'udf_strvalformax.so';
它给出了错误
ERROR 1127 (HY000): Can't find symbol 'strvalformax' in library
我还检查了共享对象文件以查看符号是否可用以及它是否可用。这是 nm -gC --demangle udf_strvalformax.so
0000000000200a50 D __bss_start
0000000000200a50 D _edata
0000000000200a50 D _end
U free
U malloc
U strcpy
U strlen
00000000000006c0 T strvalformax_add
00000000000006a0 T strvalformax_clear
0000000000000660 T strvalformax_deinit
0000000000000540 T strvalformax_init
0000000000000760 T strvalformax_reset
00000000000007a0 T strvalformax(st_udf_init*, st_udf_args*, char*, unsigned long*, char*, char*)
U operator delete(void*)
U operator new(unsigned long)
我已经尝试找出问题 1.5 天了,但没有 progress.May 因为我提前遗漏了一些东西 here.thanks。
I also checked in the shared object file to see if symbol is available or not and it is available.
不,它不在那里。 .so 包含一个损坏的符号
00000000000007a0 T strvalformax(st_udf_init*, st_udf_args*, char*, unsigned long*, char*, char*)
服务器只查找 strvalformax
。
使用普通的
nm udf_strvalformax.so
看看区别。
问题是使用 extern "C"
char* strvalformax( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
以及函数的实现
char *strvalformax ( UDF_INIT* initid, UDF_ARGS* args,char* result,unsigned long* res_length, char* is_null, char* is_error )
使用了不同的原型,所以它们不是同一个函数。
尝试使用准确的函数原型声明 extern C
(缺少参数 result
和 res_length
)。