Thread: g++ not working for postgresql extension languages?

g++ not working for postgresql extension languages?

From
Lonnie Cumberland
Date:
Hello,

Here is something very important that I think might be a bug for you to look
into as there is some aparent inconsistancies

I was doing some testing before I started to write my c++ routine to extend
PostgreSQL 7.03 on my Linux box and found this problem.

I made two copies of the same file called "funcs.c" and "funcs.cc" as can be
see below.

If I work with the "funcs.cc" file then I can get:
-------------------------------------------------------------------------

[root@Treazurac /test]# g++ -I./include -I./backend -O2 -Wall
-Wmissing-prototypes -Wmissing-declarations -I/usr/include/pgsql -I/usr/include
-fpic -c -o funcs.o funcs.cc

[root@Treazurac /test]# g++ -shared -o funcs.so funcs.o

[root@Treazurac /test]# ls

Makefile  Makefile.global  Makefile.port  funcs.cc  funcs.o  funcs.so*
funcs.sql

[root@Treazurac /test]# pico -w funcs.sql

[root@Treazurac /test]# psql -f funcs.sql -d trdata
DROP
CREATE

[root@Treazurac /test]# psql trdata
Welcome to psql, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit

trdata=# select concat_text('a','b');
ERROR:  Can't find function concat_text in file /test/funcs.so
trdata=#
--------------------------------------------------------------------------

And although I should not be running as "root", this is a test machine and it
is ok for the time being.

If I do the same thing as above, but using the "funcs.c" file (which is the
exact same file just renamed)
---------------------------------------------------------------------------
funcs.c and funcs.cc
-------------------------
#include "postgres.h"           // for variable length type

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h>
#include <unistd.h> // for unix crypt function

text *
concat_text(text *arg1, text *arg2);

text *
concat_text(text *arg1, text *arg2)
{
    int32 new_text_size = VARSIZE(arg1) + VARSIZE(arg2) - VARHDRSZ;
    text *new_text = (text *) malloc(new_text_size);

    memset((void *) new_text, 0, new_text_size);
    VARSIZE(new_text) = new_text_size;
    strncpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1)-VARHDRSZ);
    strncat(VARDATA(new_text), VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
    return (new_text);
}
--------------------------------------------------------------------------

with funcs.sql
------------------
DROP FUNCTION concat_text(text, text);
CREATE FUNCTION concat_text(text, text) RETURNS text
     AS '/test/funcs.so' LANGUAGE 'c';
----------------------------------------------------------------------------

With the "funcs.c" file in place I get:
-----------------------------------------------------------------------------
[root@Treazurac /test]# gcc -I./include -I./backend -O2 -Wall
-Wmissing-prototypes -Wmissing-declarations -I/usr/include/pgsql -I/usr/include
-fpic -c -o funcs.o funcs.c

[root@Treazurac /test]# gcc -shared -o funcs.so funcs.o

[root@Treazurac /test]# psql -f funcs.sql -d trdata
DROP
CREATE

[root@Treazurac /test]# psql trdata
Welcome to psql, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit

trdata=# select concat_text('a','b');
 concat_text
-------------
 ab
(1 row)

trdata=#
-----------------------------------------------------------------------------

so now I do not understand why the "gcc" version works and the "g++" version
does not?

Just a side note in that I can easliy compile c++ the examples in the
interfaces/libpq++ directory without any problems so that this is very strange
to me.

I really need the "g++" version to work correctly as well?

Any ideas on how to fix this so that I can use c++ functions compiled with g++
in the PL/pgSQL extensions?

Cheers
Lonnie


__________________________________________________
Do You Yahoo!?
Get email at your own domain with Yahoo! Mail.
http://personal.mail.yahoo.com/

Re: g++ not working for postgresql extension languages?

From
Thomas Lockhart
Date:
> Any ideas on how to fix this so that I can use c++ functions compiled with g++
> in the PL/pgSQL extensions?

To implement function overloading, g++ (and other c++ compilers) use
"name mangling" to allow functions and methods with the same name but
with different arguments to be handled by standard linkers. It is a
clever scheme, but it does require that you explicitly identify
functions or methods written in C++ which you will be calling from C or
from other non-C++ languages.

You will want to do this anyway (even if you could instead figure out
what the mangled name looks like and declare that as the entry point)
because C++ has features and conventions to implement, for example,
exceptions which are incompatible with the calling C code.

You make them compatible by surrounding the declaration of your C++
function with the following:

extern "C" {
 <your function prototype here...>
}

The actual implementation does not have to have this, only your
prototype declaration. The function or method name will no longer be
mangled, but of course you can not overload it either.

Good luck!

                     - Thomas