thor
thor

Reputation: 22500

using C++ functions in PostreSQL

I'm trying out the code in this blog about C++14 and postgres to test the feasibility of the well-known problem of Writing PostgreSQL Functions in C++ (with PostgreSQL 10.1, Ubuntu 16.04).

The code (extension.cpp) seems simple enough:

extern "C" {
    #include <postgres.h>    //all C headers and macros go inside extern "C"
    #include <utils/rel.h>
    PG_MODULE_MAGIC;
}

#include<vector>           //C++ headers go outside

extern "C" {
    int sumofall() {        //wrap the C++ function inside the extern "C" block
        auto sum_of_all = 0;
        std::vector<int> arr {1,2,3,4,5,6,7};
        for (auto& i : arr)
            sum_of_all += i;
        return sum_of_all;
    }
}

The code compiles, but the problem is that the C++ function cannot be found or called from PostgreSQL with the commands as follows:

g++ -c -fPIC -Wall -Werror -g3 -O0 -I$(pg_config --includedir-server) extension.cpp
g++ -shared -o my-extension.so extension.o

sudo cp my-extension.so $(pg_config --pkglibdir)

psql -U postgres -h localhost $(whoami) -c "
CREATE OR REPLACE FUNCTION 
   sumofall() RETURNS integer AS 'my-extension' 
LANGUAGE C STRICT;"

Postgres returns an error:

ERROR: could not find function information for function "sumofall" HINT: SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname).

How can I fix the issue?

Upvotes: 4

Views: 2297

Answers (2)

LittleEaster
LittleEaster

Reputation: 601

In addition to the fundamental observation of @Laurenz, you should also provide a .control file to install the extension and inform postgresql on how use it. Here I can show a .control file I've at hand now.

# file: tm_ext.control :
comment = 'Comments....'
default_version = '0.0.1'
directory = 'extension' # /usr/share/postgresql/{pg_ver}/extension/
module_pathname = '$libdir/tm_ext'
relocatable = false
schema = tm_ext

Then you have to declare functions pointing to the sharedlib like:

CREATE FUNCTION tm_ext.doit([args..]) RETURNS integer
     AS '$libdir/tm_ext', 'doit'
     LANGUAGE C STRICT;

Read the doc extend-extensions

Upvotes: 1

Laurenz Albe
Laurenz Albe

Reputation: 246523

Read the documentation:

The version-1 calling convention relies on macros to suppress most of the complexity of passing arguments and results. The C declaration of a version-1 function is always:

Datum funcname(PG_FUNCTION_ARGS)

In addition, the macro call:

PG_FUNCTION_INFO_V1(funcname);

must appear in the same source file. (Conventionally, it's written just before the function itself.)

Upvotes: 3

Related Questions