Reputation: 22500
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
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
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