Вопрос

I'm trying to implement a Netezza UDX that uses R language through Rserve (therefore I use Rconnection library for C++). Currently I've written only the bare minimum required for the UDX to run.

It looks as follows:

#define MAIN

// Netezza UDX libraries
#include "udxinc.h"
#include "udxhelpers.h"

// C++ libraries
#include <cstdlib>
#include <cstring>

// external Rserve and R headers
#include "Rconnection.h"
#include "sisocks.h"

using namespace nz::udx::dthelpers;
using namespace nz::udx_ver2;

// extends UDF base class
class My_UDX : public Udf {     

    public:
        Rconnection * rc;

        My_UDX(UdxInit *pInit) : Udf(pInit) {
            initsocks();
            // IP address in place of ...
            rc = new Rconnection("...", 6311);
        };

        ~My_UDX() {
            delete rc;
        }

        static Udf* instantiate(UdxInit *pInit);

        virtual ReturnValue evaluate();
};

Udf* My_UDX::instantiate(UdxInit *pInit) {
    return new My_UDX(pInit);
}

// called once for each row of data during execution
ReturnValue My_UDX::evaluate() {

    int32 retval = 15;

    NZ_UDX_RETURN_INT32(retval);
}

The problem arises when I try to test the UDX with a SQL query. My query looks like this:

SELECT * FROM table_name WHERE My_UDX(table_field) = 1;

And this is the error message I get:

Testing...
nzsql -d database_name -u my_username -pw my_password -f sql/test.sql
nzsql:sql/test.sql:1: ERROR:  /dev/shm/spuplans/63_1_3.o: undefined symbol: _ZN11RconnectionC1EPKci : loading executable code
make: *** [update] Error 2

If I remove the Rconnection object, UDX works just fine.

I've checked different manuals about Netezza UDXs, Rserve, and Rconnection but with no results. Couldn't find any explanation to this error and what could be done to resolve it.

Then I assumed there might be something wrong with the compiling process, inclusion of needed libraries and flags. I'm not so familiar with makefiles so this is quite a possibility. My makefile looks like so:

# list of files
function_name   = My_UDX
object_files    = $(function_name).o_x86
spu_files       = $(function_name).o_spu10

# database connection
db_call = nzsql -d database_name -u my_username -pw my_password -f

# path to directories
lib_dir             = /home/nz/libs
r_connection_dir    = /home/nz/Rconnection

all: update

update: compile
    $(db_call) sql/unload.sql
    cp $(object_files) $(lib_dir)
    cp $(spu_files) $(lib_dir)
    rm -f *.o_spu10 *.o_x86
    $(db_call) sql/create.sql
    $(db_call) sql/test.sql

compile:
    nzudxcompile $(function_name).cpp --args -I$(r_connection_dir)

unload.sql just drops the previously loaded function and create.sql just creates it. The problem arises only when the test.sql with the previously shown SQL query is executed.

Have been trying to resolve this issue for quite a long time so any help would be appreciated!

Это было полезно?

Решение

As mentioned above by Alex, Rconnection had to be loaded as a shared library or compiled along with the UDF. Solved this by compiling with the UDF.

# for host environment
nzudxcompile --host Rconnection.cpp -o temp_rconnection.o_x86
nzudxcompile --host myudf.cpp -o temp_myudf.o_x86
nzudxcompile --host --objs temp_rconnection.o_x86 --objs temp_myudf.o_x86 -o myudf.o_x86

# for spu environment
nzudxcompile Rconnection.cpp --spu -o temp_rconnection.o_spu10
nzudxcompile myudf.cpp --spu -o temp_myudf.o_spu10
nzudxcompile --spu --objs temp_rconnection.o_spu10 --objs temp_myudf.o_spu10 -o    myudf.o_spu10
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top