2016-11-11 72 views
2

我一直試圖添加用戶定義的函數在MySQL 5.6中執行一個簡單的任務 - 即找到最大值column1和返回另一列的值,即column2對應於column1的最大值。試圖在mysql中添加udf給出錯誤錯誤1127(HY000):無法找到庫中的符號

我知道這個概念中幾乎沒有什麼警告,例如如果column1的2個最大值,那麼應該返回column2的哪個對應值。但這些東西現在不是我主要關注的領域。

我已經寫的程序在其列1列2和兩個雙打功能。它正在運行。但是,當我嘗試的情況下,column1是double和column2是string類型。我面臨的問題是,它給出了錯誤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 

命令用於編譯和鏈接用於鏈接到共享庫 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

命令 ld -shared -o udf_strvalformax.so udf_strvalformax.o

複製的共享對象文件到MySQL插件LIB 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結果。

回答

1

我還檢查了共享對象文件中,以查看是否符號是可用的 與否,它是可用的。

不,它不存在。 .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與確切的函數原型(參數resultres_length缺失)。

+0

感謝marc這樣的noob錯誤我做到了。我對nm的理解並不合格。 –