Обсуждение: Problem with DirectFunctionCall3(array_in,...)

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

Problem with DirectFunctionCall3(array_in,...)

От
Jessica Ditt
Дата:
Hi!

At the moment I'm trying to create an own datatype "timeseries", which should contain among others an array of float8 values.

As far as I know, float8 is a base type of postgres and therefore I shouldn't need to create an own array-type.

In my own C-function "timeseries_in()" I would like to use "array_in()" implemented in arrayfuncs.c. To insert a timestamp with timezone, I'm using

DirectFunctionCall3(timestamptz_in, CStringGetDatum(zeitstempel), ObjectIdGetDatum(InvalidOid), Int32GetDatum(-1));

and it works fine... Trying the same with

DirectFunctionCall3(array_in, CStringGetDatum(arraystring), ObjectIdGetDatum(20), Int32GetDatum(-1));

unfortunately smashes my postmaster...

Having done a lot of research, I can't spot the mistake. Does anyone know the problem or have a workaround for me?

Please tell me, if you want me to supply my source code or anything else...

MfG
Jessica

Re: Problem with DirectFunctionCall3(array_in,...)

От
Michael Fuhr
Дата:
On Thu, Apr 28, 2005 at 02:11:29PM +0200, Jessica Ditt wrote:
>
> DirectFunctionCall3(array_in, CStringGetDatum(arraystring),
> ObjectIdGetDatum(20), Int32GetDatum(-1));
>
> unfortunately smashes my postmaster...

Running a debugger on the core dump shows a segmentation fault at
the following line in array_in() in arrayfuncs.c:

    my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;

Examining the data shows that fcinfo->flinfo is NULL; presumably
dereferencing it caused the segmentation fault.  Looking at the
code for DirectFunctionCall3() in fmgr.c, we see that it initializes
fcinfo by calling InitFunctionCallInfoData() with the second argument
set to NULL, which gets assigned to flinfo.  Apparently that's the
problem.

I don't know if the following is The Right Way To Do It, but it
works for me in simple tests:

    Datum  a;

    a = OidFunctionCall3(F_ARRAY_IN,
                         CStringGetDatum(arraystring),
                         ObjectIdGetDatum(INT8OID),
                         -1);

F_ARRAY_IN is defined in utils/fmgroids.h; INT8OID is defined in
catalog/pg_type.h.

Before using the above code, you might want to see if one of the
developers follows up.  There might be a different way that's
considered best practice.

--
Michael Fuhr
http://www.fuhr.org/~mfuhr/

Re: Problem with DirectFunctionCall3(array_in,...)

От
Tom Lane
Дата:
Michael Fuhr <mike@fuhr.org> writes:
> Examining the data shows that fcinfo->flinfo is NULL; presumably
> dereferencing it caused the segmentation fault.  Looking at the
> code for DirectFunctionCall3() in fmgr.c, we see that it initializes
> fcinfo by calling InitFunctionCallInfoData() with the second argument
> set to NULL, which gets assigned to flinfo.  Apparently that's the
> problem.

This is the intended and documented behavior --- see fmgr/README:

: The DirectFunctionCallN routines will not bother to fill in
: fcinfo->flinfo (indeed cannot, since they have no idea about an OID for
: the target function); they will just set it NULL.

It would maybe be possible for them to create an only-partially-valid
flinfo, but I think that would simply lead to easier-to-miss bugs.
In any case it'd be a waste of cycles in the vast majority of calls.

Realistically you don't want to call array_in this way anyhow, since
its setup overhead is so high.  You want to have a flinfo struct for it
that will persist for the entire query, if at all possible.  That is
you want one fmgr_info() call and then a series of FunctionCallN() calls.

            regards, tom lane

Re: Problem with DirectFunctionCall3(array_in,...)

От
"Jessica Ditt"
Дата:
Thank you very, very much so far.

>This is the intended and documented behavior --- see fmgr/README:

>: The DirectFunctionCallN routines will not bother to fill in
>: fcinfo->flinfo (indeed cannot, since they have no idea about an OID for
>: the target function); they will just set it NULL.

I actually read this text, but somehow did not consider it as solution to my
problem.

I think, I'll have a closer look at the involved structures as well as the
system of calling existing functions now.

I'd be glad, if you assist me with further emerging problems in the future
;)

kind regards, Jessica