3

I am working on Linux Mint 17 Qiana with MySQL Ver 14.14 Distrib 5.5.53, for debian-linux-gnu (x86_64).

Following the instructions found here:

http://dev.mysql.com/doc/refman/5.7/en/adding-udf.html

and subsequent pages, I have created a library file for my own user-defined function. But MySQL gives an error when I create the MySQL function from the library file.

Here are the steps I made.

I have created the following C file:

#include <math.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <mysql/mysql.h>

//*** Functions for compressing a protein sequence into a binary
my_bool compress_protein_sequence_init(UDF_INIT* initid, UDF_ARGS* args, char* message) {
    if(args->arg_count != 1) {
        strcpy(message, "Error: compress_protein_sequence needs a string");
        return 1;
    }

    if( args->arg_type[0] != STRING_RESULT ) {
        args->arg_type[0] = STRING_RESULT;
    }

    return 0;
}

char* compress_protein_sequence(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* ret_length, char* is_null, char* error) {
    unsigned long length = args->lengths[0];

//*** Checking on the arguments

    *ret_length = (unsigned long) length;

    if(!(result = malloc(sizeof(char) * ((*ret_length) + 1)))) {
        *is_null = 1;
        *error=1;
        *ret_length = 0;
        return 0;
    }
    if(initid->ptr) {
        free(initid->ptr);
    }
    initid->ptr = result;

    memset( result, '\0', *ret_length + 1 );

//*** Some logic

    result[*ret_length] = '\0';
    return result;
}

void compress_protein_sequence_deinit(UDF_INIT* initid) {
    if( initid->ptr )
        free( initid->ptr );
}

I compile the C code:

gcc -Wall -I/usr/local/include -shared -o libcompress_sequence.so -c compress_sequence.c

MySQL plugin directory is given by:

SHOW VARIABLES LIKE '%plugin%';

the answer is:

+---------------+------------------------+
| Variable_name | Value                  |
+---------------+------------------------+
| plugin_dir    | /usr/lib/mysql/plugin/ |
+---------------+------------------------+

So I put the libcompress_sequence.so in the plugin folder of MySQL:

sudo cp libcompress_sequence.so /usr/lib/mysql/plugin/

I start MySQL in command line as root:

mysql -u root -p

I chose a database then I execute this MySQL command:

CREATE FUNCTION COMPRESS_PROTEIN_SEQUENCE RETURNS STRING SONAME 'libcompress_sequence.so';

and MySQL shows this error:

ERROR 1126 (HY000): Can't open shared library 'libcompress_sequence.so' (errno: 0 /usr/lib/mysql/plugin/libcompress_sequence.so: only ET_DYN and ET_EXEC can be loaded)

What is ET_DYN? What is ET_EXEC? What is happening? How to solve the problem?

1 Answers1

4

The issue has been solved by:

removing the -c option from the gcc command line and adding the -fPIC option at the end, turning the command line into:

gcc -Wall -I/usr/local/include -shared -o libcompress_sequence.so compress_sequence.c -fPIC

The -c option removed the linking, which is not wished here since the library is compiled in one step. So removing the -c option tells to gcc to make the linking with the libraries included in the C file. But then gcc didn't compile anymore, and complained about the option -fPIC missing. I added it and gcc compiled.

Then MySQL complained about not being able to detect the function COMPRESS_PROTEIN_SEQUENCE in my library. So I put it in small letters: compress_protein_sequence, as the function is named into my C code, then MySQL imported the library. The actual MySQL command is the following:

CREATE FUNCTION compress_protein_sequence RETURNS STRING SONAME 'libcompress_sequence.so';

I am now able to use the MySQL function COMPRESS_PROTEIN_SEQUENCE.