2016-11-11 7 views
2

単純なタスクを実行するmysql 5.6にユーザー定義関数を追加しようとしています。別の列、つまりcolumn1の最大値に対応するcolumn2の値を返します。mysqlにudfを追加しようとするとエラーが発生するERROR 1127(HY000):ライブラリ内のシンボルを見つけることができない

この概念には、column1の2つの最大値、次にcolumn2の対応する値が返される場合のようないくつかの警告があることは知っています。しかし、これらのことは私の主な焦点ではありません。

私は既にcolumn1とcolumn2の両方がdouble型の関数のプログラムを書いています。実行中です。しかし、私が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関数を呼び出す 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は、サーバがちょうどstrvalformax探しマングルされたシンボル

00000000000007a0 T strvalformax(st_udf_init*, st_udf_args*, char*, unsigned long*, char*, char*) 

が含まれています。

違いを見るために、プレーン

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) 

は異なるプロトタイプを使用する機能の実装を使用するので、これらは同一の機能ではないということです。

正確な関数プロトタイプ(パラメータresultres_lengthがない)を指定してextern Cを宣言してください。

+0

ありがとうございました。 nmの私の理解はマークまでではなかった。 –

関連する問題