Creating server-side functions: one simple error

Started by Ruslan A Dautkhanovover 23 years ago10 messagesbugs
Jump to latest
#1Ruslan A Dautkhanov
rusland@scn.ru

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

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Ruslan A Dautkhanov (#1)
Re: Creating server-side functions: one simple error

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

#3Ruslan A Dautkhanov
rusland@scn.ru
In reply to: Ruslan A Dautkhanov (#1)
Re: Creating server-side functions: one simple error

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

#4Joe Conway
mail@joeconway.com
In reply to: Ruslan A Dautkhanov (#1)
Re: Creating server-side functions: one simple error

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

#5Ruslan A Dautkhanov
rusland@scn.ru
In reply to: Ruslan A Dautkhanov (#1)
Re: Creating server-side functions: one simple error

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

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Ruslan A Dautkhanov (#5)
Re: Creating server-side functions: one simple error

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

#7Ruslan A Dautkhanov
rusland@scn.ru
In reply to: Ruslan A Dautkhanov (#1)
Re: Creating server-side functions: one simple error

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

#8elein
elein@sbcglobal.net
In reply to: Ruslan A Dautkhanov (#7)
Re: Creating server-side functions: one simple error

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

Show quoted text

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 = 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

---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org

#9Peter Eisentraut
peter_e@gmx.net
In reply to: Ruslan A Dautkhanov (#7)
Re: Creating server-side functions: one simple error

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

#10Joe Conway
mail@joeconway.com
In reply to: elein (#8)
Re: Creating server-side functions: one simple error

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