Thread: Extending PostgreSQL in C or C++

Extending PostgreSQL in C or C++

From
Sebastien Lemieux
Date:
Hi,
 I need to extend postgreSQL to support some specific function I will 
code in C (ideally C++ if it can work!).  I'm trying to run some simple 
test and it doesn't seem to work.  Here is the C code:

----------
#include "postgres.h"
#include <string.h>

int
add_one(int arg)
{ return arg + 1;
}
----------

Which is compiled with:
gcc -fpic -c -I/[ThePath]/postgresql-7.3.2/include/server/ pgsql_bio.c
gcc -shared -o pgsql_bio.so pgsql_bio.o

It compiles fine.

And then in postgreSQL as user postgres in database template1:
CREATE FUNCTION add_one(int4) RETURNS int4    AS '/[PathToTheObject]/pgsql_bio.so' LANGUAGE C    WITH (isStrict);

Then I get:
ERROR:  Can't find function add_one in file /[PathToTheObject]/pgsql_bio.so

I'm using PostgreSQL 7.3.2 on Redhat 7.2 (linux 2.4.7-10) and compiling 
with gcc 2.95.3.

Following some suggestions I found on usenet, I ran 'nm' on the library 
and I got the expected entry for my function:
00000700 T add_one

Anyone has an idea about what I am doing wrong?  Any suggestion will be 
welcome!

thanks,

-- 
Sebastien Lemieux
Bioinformatics, post-doc
Elitra-canada



Re: Extending PostgreSQL in C or C++

From
David Blasby
Date:
Sebastien Lemieux wrote:
> Hi,
> 
>   I need to extend postgreSQL to support some specific function I will 
> code in C (ideally C++ if it can work!). 

Be very carefull with using C++ functions inside postgresql.  If the C++ 
code throws an exception the postgresql backend will get a SIGABRT and 
terminate.

You can solve this by linking the std c++ library to the postmaster.  We 
tried everything we could think of to fix this, but this was the only 
solution that worked.

For a complete discussion, you can read the PostGIS (GIS spatial objects 
for Postgresql) mailing list (http://postgis.refractions.net) and the 
GEOS (Geometry Engine, Open Source) mailing list 
(http://geos.refractions.net).

dave



Re: Extending PostgreSQL in C or C++

From
Tom Lane
Date:
Sebastien Lemieux <slemieux@elitra.com> writes:
> Then I get:
> ERROR:  Can't find function add_one in file /[PathToTheObject]/pgsql_bio.so

Hmm.  I can't see anything wrong with what you did, either.

It's possible that the dynamic linker has printed additional messages to
the backend's stderr.  Make sure that you have stderr set up to go
someplace useful (not /dev/null) and look there to see if you can learn
more.
        regards, tom lane


Re: Extending PostgreSQL in C or C++

From
Andreas Pflug
Date:
David Blasby wrote:

> Sebastien Lemieux wrote:
>
>> Hi,
>>
>>   I need to extend postgreSQL to support some specific function I 
>> will code in C (ideally C++ if it can work!). 
>
>
> Be very carefull with using C++ functions inside postgresql.  If the 
> C++ code throws an exception the postgresql backend will get a SIGABRT 
> and terminate.
>
> You can solve this by linking the std c++ library to the postmaster.  
> We tried everything we could think of to fix this, but this was the 
> only solution that worked.
>
> For a complete discussion, you can read the PostGIS (GIS spatial 
> objects for Postgresql) mailing list (http://postgis.refractions.net) 
> and the GEOS (Geometry Engine, Open Source) mailing list 
> (http://geos.refractions.net).
>
If you try C++, you will find some nasty name/reserved words collisions, 
but it will work:

#define using __using
#define typeid __typeid
#define typename __typename
#define namespace __namespace
#define delete __delete
extern "C"
{
#include "postgres.h"
#include "executor/spi.h"
#include "funcapi.h"
}
#undef using
#undef typeid
#undef typename
#undef namespace
#undef delete

Fortunately, my code didn't use exceptions...
Regards,
Andreas




Re: Extending PostgreSQL in C or C++

From
Christof Petig
Date:
Tom Lane wrote:
> Sebastien Lemieux <slemieux@elitra.com> writes:
> 
>>Then I get:
>>ERROR:  Can't find function add_one in file /[PathToTheObject]/pgsql_bio.so
> 
> 
> Hmm.  I can't see anything wrong with what you did, either.
> 
> It's possible that the dynamic linker has printed additional messages to
> the backend's stderr.  Make sure that you have stderr set up to go
> someplace useful (not /dev/null) and look there to see if you can learn
> more.

most likely he has to declare the function as extern "C". A nm 
pgsql_bio.so can tell more.
   Christof