Обсуждение: Creating server-side functions: one simple error

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

Creating server-side functions: one simple error

От
Ruslan A Dautkhanov
Дата:
Hi,

I have to create my own function in C lanuage, which
will use SPI. The problem that when I had done all things,
PostgreSQL says:
    isbs=# select pgf1test('123');
    ERROR:  Can't find function pgf1test in file /usr/local/pgsql/lib/pgf1test.so

I don't know where problems is. The program is very short, please
point me where my mistake?

pgf1test.c
----------
    #include "executor/spi.h"
    #include <ctype.h>

    Datum           pgf1test(PG_FUNCTION_ARGS);
    PG_FUNCTION_INFO_V1(pgf1test);

    Datum
    pgf1test(PG_FUNCTION_ARGS)
    {
    //      text  tnum = PG_GETARG_NAME(0);
            char *cnum = PG_GETARG_CSTRING(0);
            PG_RETURN_INT32( atoi(cnum) );
    }


compile.sh
----------
    #!/bin/sh

    NAME=pgf1test

    gcc -pipe -O2 -Wall -Wmissing-prototypes -Wmissing-declarations -fpic -DPIC \
        -I. -I/usr/home/rd/postgresql/src/include -c -o ${NAME}.o ${NAME}.c

    /usr/libexec/elf/ld -x -shared -o ${NAME}.so ${NAME}.o
    rm ${NAME}.o

pgf1test-createfunc.sql
-----------------------
    CREATE OR REPLACE FUNCTION pgf1test (text)
            RETURNS int4
            AS '$libdir/pgf1test'
            LANGUAGE 'C' WITH (isStrict);



    All that files worked well - I have created .so object and installed it
    into /usr/local/pgsql/lib/, after that I execute pgf1test-createfunc.sql -
    it's complete successfully, but
        isbs=# select pgf1test('123');
        ERROR:  Can't find function pgf1test in file /usr/local/pgsql/lib/pgf1test.so

show errors. Why PostgreSQL can't found C-function? I know that problem
is not complex, and it's very simple question for you. Thanks.

---
 best regards,
Ruslan A Dautkhanov

Re: Creating server-side functions: one simple error

От
Tom Lane
Дата:
Ruslan A Dautkhanov <rusland@scn.ru> writes:
> I have to create my own function in C lanuage, which
> will use SPI. The problem that when I had done all things,
> PostgreSQL says:
>     isbs=# select pgf1test('123');
>     ERROR:  Can't find function pgf1test in file /usr/local/pgsql/lib/pgf1test.so

But it got past the CREATE FUNCTION command without complaint?  That's
odd, because CREATE FUNCTION should make the same check.

Does the behavior change if you start a fresh session?  If so, see
the LOAD command, which you need to use (or start a fresh session)
after any change of the shared library file.

            regards, tom lane

Re: Creating server-side functions: one simple error

От
Ruslan A Dautkhanov
Дата:
Tom Lane wrote:

> Ruslan A Dautkhanov <rusland@scn.ru> writes:
> > I have to create my own function in C lanuage, which
> > will use SPI. The problem that when I had done all things,
> > PostgreSQL says:
> >     isbs=# select pgf1test('123');
> >     ERROR:  Can't find function pgf1test in file /usr/local/pgsql/lib/pgf1test.so
>
> But it got past the CREATE FUNCTION command without complaint?  That's
> odd, because CREATE FUNCTION should make the same check.
>
> Does the behavior change if you start a fresh session?  If so, see
> the LOAD command, which you need to use (or start a fresh session)
> after any change of the shared library file.
>
>                         regards, tom lane

Yes, you right, I just must run LOAD - after LOAD had complete all works good. Thanks.
Btw, how I can convert TEXT field to a CString one? I had tried to use
  char *cnum = PG_GETARG_CSTRING(0)  instead of
  text tnum = PG_GETARG_NAME(0),   but it's not worked properly. Is any function
to convert text object to a null-terminated string??? Thanks again.


--
  best regards,
 Ruslan A Dautkhanov   rusland@scn.ru

Re: Creating server-side functions: one simple error

От
Joe Conway
Дата:
Ruslan A Dautkhanov wrote:
> Btw, how I can convert TEXT field to a CString one? I had tried to use
>   char *cnum = PG_GETARG_CSTRING(0)  instead of
>   text tnum = PG_GETARG_NAME(0),   but it's not worked properly. Is any function
> to convert text object to a null-terminated string??? Thanks again.
>

I like to use the following macros:

/* convert C string to text pointer */
#define GET_TEXT(cstrp) \
     DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(cstrp)))
/* convert text pointer to C string */
#define GET_STR(textp) \
     DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(textp)))

then you can do, e.g.
   char   *cnum = GET_STR(PG_GETARG_TEXT_P(0));

BTW, there are lots of good examples of C functions in contrib.

HTH,

Joe

Re: Creating server-side functions: one simple error

От
Ruslan A Dautkhanov
Дата:
Joe Conway wrote:

> Ruslan A Dautkhanov wrote:
> > Btw, how I can convert TEXT field to a CString one? I had tried to use
> >   char *cnum = PG_GETARG_CSTRING(0)  instead of
> >   text tnum = PG_GETARG_NAME(0),   but it's not worked properly. Is any function
> > to convert text object to a null-terminated string??? Thanks again.
> >
>
> I like to use the following macros:
>
> /* convert C string to text pointer */
> #define GET_TEXT(cstrp) \
>      DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(cstrp)))
> /* convert text pointer to C string */
> #define GET_STR(textp) \
>      DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(textp)))
>
> then you can do, e.g.
>    char   *cnum = GET_STR(PG_GETARG_TEXT_P(0));

    Thanks, this worked good. I had finished testing of creating
server-side functions and starts creating my business-oriented things on
SPI, and I have trap again - I can't translate datetime column, which
pass to my procedure. I must convert it to UNIX 1970-seconds counter for
my internal needs, but I havn't found _any_ PG_GETARG_* function in fmgr.h,
which can read time types as procedure's arguments. Sorry for this question,
but PG_GETARG_* function is not documented anywhere...


---
  best regards,
Ruslan A Dautkhanov   rusland@scn.ru

Re: Creating server-side functions: one simple error

От
Tom Lane
Дата:
Ruslan A Dautkhanov <rusland@scn.ru> writes:
> SPI, and I have trap again - I can't translate datetime column, which
> pass to my procedure. I must convert it to UNIX 1970-seconds counter for
> my internal needs, but I havn't found _any_ PG_GETARG_* function in fmgr.h,
> which can read time types as procedure's arguments.

Not all the GETARG functions are in fmgr.h, only the most widely used
types.  See utils/timestamp.h.

            regards, tom lane

Re: Creating server-side functions: one simple error

От
Ruslan A Dautkhanov
Дата:
Tom Lane wrote:

> Ruslan A Dautkhanov <rusland@scn.ru> writes:
> > SPI, and I have trap again - I can't translate datetime column, which
> > pass to my procedure. I must convert it to UNIX 1970-seconds counter for
> > my internal needs, but I havn't found _any_ PG_GETARG_* function in fmgr.h,
> > which can read time types as procedure's arguments.
>
> Not all the GETARG functions are in fmgr.h, only the most widely used
> types.  See utils/timestamp.h.

    Hi! Yes, you right, it's works well - I'm using PG_GETARG_TIMESTAMPTZ()
from utils/timestamp.h. But I have another problem when I try to compile procedure
with my own library, which used C++-like things. More exactly, problem begins
when I include .h file - it's not compiled since it used C++ constructions.
That is why I had renamed .c file to .cc - gcc understand source as C++ code now.
After this I have no problems in my header files, but have many in PG's
header files, for example:
1.    In file included from /usr/home/rd/postgresql/src/include/executor/spi.h:22,
                 from remain_time.cc:2:
      /usr/home/rd/postgresql/src/include/nodes/primnodes.h:529: syntax error before `using'

2.    In file included from /usr/home/rd/postgresql/src/include/nodes/relation.h:18,
                 from /usr/home/rd/postgresql/src/include/executor/spi.h:23,
                 from remain_time.cc:2:
      /usr/home/rd/postgresql/src/include/nodes/parsenodes.h:967: syntax error before `typename'
      ... (other similar errors on different parsenodes.h's lines)

... other errors on PG's headers when I tries to create procedure as C++ function.
Is this mean, that PostgreSQL not C++-ready for compiling server-side functions, doesn't it?
Is any methods exists for compiling procedure in C++ (namespace modifications etc)??
Thanks for your help.


---
  best regards,
Ruslan A Dautkhanov   rusland@scn.ru

Re: Creating server-side functions: one simple error

От
elein (by way of elein
Дата:
This will not work if there is no EOS on the data portion of the
string.  Text fields are not usually stored with the EOS on them,
are they?

elein
elein@norcov.com

On Wednesday 09 October 2002 21:14, Joe Conway wrote:
> Ruslan A Dautkhanov wrote:
> > Btw, how I can convert TEXT field to a CString one? I had tried to use
> >   char *cnum =3D PG_GETARG_CSTRING(0)  instead of
> >   text tnum =3D PG_GETARG_NAME(0),   but it's not worked properly. Is a=
ny
> > function to convert text object to a null-terminated string??? Thanks
> > again.
>
> I like to use the following macros:
>
> /* convert C string to text pointer */
> #define GET_TEXT(cstrp) \
>      DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(cstrp)))
> /* convert text pointer to C string */
> #define GET_STR(textp) \
>      DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(textp)))
>
> then you can do, e.g.
>    char   *cnum =3D GET_STR(PG_GETARG_TEXT_P(0));
>
> BTW, there are lots of good examples of C functions in contrib.
>
> HTH,
>
> Joe
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org

Re: Creating server-side functions: one simple error

От
Peter Eisentraut
Дата:
Ruslan A Dautkhanov writes:

> Is this mean, that PostgreSQL not C++-ready for compiling server-side
> functions, doesn't it?

PostgreSQL is written in C and does not claim to be compilable by a C++
compiler.  That includes the header files.

> Is any methods exists for compiling procedure in
> C++ (namespace modifications etc)?? Thanks for your help.

Make a small wrapper that you compile with a C compiler and put the actual
C++ implementation into a separate file.  Maybe you could make a complete
C++ language handler out of that.

--
Peter Eisentraut   peter_e@gmx.net

Re: Creating server-side functions: one simple error

От
Joe Conway
Дата:
elein (by way of elein ) wrote:
> This will not work if there is no EOS on the data portion of the
> string.  Text fields are not usually stored with the EOS on them,
> are they?

Yes, the TEXT data type is NULL terminated.

Joe