Обсуждение: Problems using palloc in postgresql user C functions

Поиск
Список
Период
Сортировка

Problems using palloc in postgresql user C functions

От
John Gunther
Дата:
Since I'm a novice C programmer, this may be a bonehead question, so
please be gentle if the answer is obvious.

I'm creating a shared library of PostgreSQL user functions written in C.
A couple of PG facilities appear very convenient or essential tools for
use in user functions: the palloc function (to allocate PG memory) and
the PG_STR_GET_TEXT and PG_TEXT_GET_STR macros (used to convert between
PG text strings and regular C strings).  The problem that arises when I
use these, though, is that they generate unresolved references,
requiring including a seemingly endless chain of dependent PG source
files in the compilation of the library.

Am I way off here, or does using these features massively complicate
compiling and linking my library?

Thanks for any enlightenment?

John Gunther




Re: Problems using palloc in postgresql user C functions

От
Joe Conway
Дата:
John Gunther wrote:
> I'm creating a shared library of PostgreSQL user functions written in C.
> A couple of PG facilities appear very convenient or essential tools for
> use in user functions: the palloc function (to allocate PG memory) and
> the PG_STR_GET_TEXT and PG_TEXT_GET_STR macros (used to convert between
> PG text strings and regular C strings).  The problem that arises when I
> use these, though, is that they generate unresolved references,
> requiring including a seemingly endless chain of dependent PG source
> files in the compilation of the library.
>

PG_TEXT_GET_STR and PG_STR_GET_TEXT are only locally defined in
varlena.c. You'll need to define these yourself:
#define PG_TEXT_GET_STR(textp_) \
   DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(textp_)))
#define PG_STR_GET_TEXT(str_) \
   DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(str_)))

palloc is defined in src/include/utils/palloc.h, so you need to include
that or more likely postgres.h which will include it for you, i.e.:
#include "postgres.h"

Try studying one of the contrib libraries for examples of use (e.g.
contrib/tablefunc makes use of a GET_STR macro that is the same as
PG_TEXT_GET_STR).

HTH,

Joe


Re: Problems using palloc in postgresql user C functions

От
John Gunther
Дата:
Joe,

Thanks for the fast, late night answer. I've got that much. But when I
compile and link my library with those statements (using libtool and
gcc) I get "undefined reference" errors for the following: textin,
textout, DirectFunctionCall1, CurrentMemoryContext,  MemoryContextAlloc,
and pg_detoast_datum. Handling these errors is where my understanding
fails? Can they be ignored somehow because they will be resolved at
execution time? It looks like they're fatal and preventing the library
from being created.

John

Joe Conway wrote:

> John Gunther wrote:
>
>> I'm creating a shared library of PostgreSQL user functions written in
>> C. A couple of PG facilities appear very convenient or essential
>> tools for use in user functions: the palloc function (to allocate PG
>> memory) and the PG_STR_GET_TEXT and PG_TEXT_GET_STR macros (used to
>> convert between PG text strings and regular C strings).  The problem
>> that arises when I use these, though, is that they generate
>> unresolved references, requiring including a seemingly endless chain
>> of dependent PG source files in the compilation of the library.
>>
>
> PG_TEXT_GET_STR and PG_STR_GET_TEXT are only locally defined in
> varlena.c. You'll need to define these yourself:
> #define PG_TEXT_GET_STR(textp_) \
>   DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(textp_)))
> #define PG_STR_GET_TEXT(str_) \
>   DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(str_)))
>
> palloc is defined in src/include/utils/palloc.h, so you need to
> include that or more likely postgres.h which will include it for you,
> i.e.:
> #include "postgres.h"
>
> Try studying one of the contrib libraries for examples of use (e.g.
> contrib/tablefunc makes use of a GET_STR macro that is the same as
> PG_TEXT_GET_STR).
>
> HTH,
>
> Joe
>
>
>


Re: Problems using palloc in postgresql user C functions

От
Joe Conway
Дата:
John Gunther wrote:
> Thanks for the fast, late night answer. I've got that much. But when I
> compile and link my library with those statements (using libtool and
> gcc) I get "undefined reference" errors for the following: textin,
> textout, DirectFunctionCall1, CurrentMemoryContext,  MemoryContextAlloc,
> and pg_detoast_datum. Handling these errors is where my understanding
> fails? Can they be ignored somehow because they will be resolved at
> execution time? It looks like they're fatal and preventing the library
> from being created.
>

No, they can't be ignored. I'd guess you need the following includes at
a minimum:

#include "postgres.h"
#include "fmgr.h"

Beyond that, you may need:
#include "utils/builtins.h"

and if you are using SPI:
#include "executor/spi.h"

and possibly others.

The bottom line is you need to find the header file that defines the
functionality you want to use. I recommend you read:
http://www.us.postgresql.org/users-lounge/docs/7.3/postgres/xfunc-c.html
(use the "Version-1 Calling Conventions for C-Language Functions" _not_
Version-0). And like I already mentioned, studying one or more of the
contrib libraries closely would be a very good idea.

Joe


Re: Problems using palloc in postgresql user C functions

От
John Gunther
Дата:
I haven't been explaining my exact problem clearly, but looking at your
tablefunc, I'm sure the issue is just a simple conceptual gap on my part.

In line with your responses, I'm already supplying my library with the
prototypes for all the needed PG functions, like textin. The problem is
when compiling and linking, how does libtool/gcc find or point to the
actual code for textin so it can execute it when needed. That is, the
compiler knows what textin is and the types of its arguments, but how
does it know where it is? That's what the "undefined reference" errors
are denoting. Clearly there's a way, since tablefunc doesn't include the
source code for textin, even though it calls that function. I'm just too
new to gcc to know what it is.

Joe Conway wrote:

> John Gunther wrote:
>
>> Thanks for the fast, late night answer. I've got that much. But when
>> I compile and link my library with those statements (using libtool
>> and gcc) I get "undefined reference" errors for the following:
>> textin, textout, DirectFunctionCall1, CurrentMemoryContext,
>> MemoryContextAlloc, and pg_detoast_datum. Handling these errors is
>> where my understanding fails? Can they be ignored somehow because
>> they will be resolved at execution time? It looks like they're fatal
>> and preventing the library from being created.
>>
>
> No, they can't be ignored. I'd guess you need the following includes
> at a minimum:
>
> #include "postgres.h"
> #include "fmgr.h"
>
> Beyond that, you may need:
> #include "utils/builtins.h"
>
> and if you are using SPI:
> #include "executor/spi.h"
>
> and possibly others.
>
> The bottom line is you need to find the header file that defines the
> functionality you want to use. I recommend you read:
> http://www.us.postgresql.org/users-lounge/docs/7.3/postgres/xfunc-c.html
> (use the "Version-1 Calling Conventions for C-Language Functions"
> _not_ Version-0). And like I already mentioned, studying one or more
> of the contrib libraries closely would be a very good idea.
>
> Joe
>
>
>


Re: Problems using palloc in postgresql user C functions

От
Tom Lane
Дата:
John Gunther <inbox@bucksvsbytes.com> writes:
> In line with your responses, I'm already supplying my library with the
> prototypes for all the needed PG functions, like textin. The problem is
> when compiling and linking, how does libtool/gcc find or point to the
> actual code for textin so it can execute it when needed.

It doesn't.  You should be building a shared library, not a standalone
executable.  Unresolved references get bound when the library is loaded
by the backend, not when the library is built.

I'd suggest building one of the backend-extension modules in contrib/,
and looking to see what commands get used to compile and link on your
platform.

            regards, tom lane

Re: Problems using palloc in postgresql user C functions

От
Joe Conway
Дата:
Tom Lane wrote:
> I'd suggest building one of the backend-extension modules in contrib/,
> and looking to see what commands get used to compile and link on your
> platform.
>

Another suggestion is to put your extension in a directory under
contrib, and copy and edit another contrib's Makefile. They are pretty
simple, e.g. let's say your library is called foo, and you put foo.c,
foo.h, and foo.sql.in in contrib/foo. Your Makefile would look like:

8<-------------------------------------
subdir = contrib/foo
top_builddir = ../..
include $(top_builddir)/src/Makefile.global

MODULES = foo
DATA_built = foo.sql

include $(top_srcdir)/contrib/contrib-global.mk
8<-------------------------------------

Now you can do (from contrib/foo):

   make
   make install
   psql myfoodatabase < foo.sql

to build and install foo.so.

For more info on the contrib Makefile layout and variables, look at the
comments in contrib/contrib-global.mk

Joe


Re: Problems using palloc in postgresql user C functions

От
John Gunther
Дата:
Thank you, gentlemen. With your kind assistance, I've succeeded in
creating my first C language pg function..

Joe Conway wrote:

> Tom Lane wrote:
>
>> I'd suggest building one of the backend-extension modules in contrib/,
>> and looking to see what commands get used to compile and link on your
>> platform.
>>
>
> Another suggestion is to put your extension in a directory under
> contrib, and copy and edit another contrib's Makefile. They are pretty
> simple, e.g. let's say your library is called foo, and you put foo.c,
> foo.h, and foo.sql.in in contrib/foo. Your Makefile would look like:
>
> 8<-------------------------------------
> subdir = contrib/foo
> top_builddir = ../..
> include $(top_builddir)/src/Makefile.global
>
> MODULES = foo
> DATA_built = foo.sql
>
> include $(top_srcdir)/contrib/contrib-global.mk
> 8<-------------------------------------
>
> Now you can do (from contrib/foo):
>
>   make
>   make install
>   psql myfoodatabase < foo.sql
>
> to build and install foo.so.
>
> For more info on the contrib Makefile layout and variables, look at
> the comments in contrib/contrib-global.mk
>
> Joe
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster
>
>