Thread: Defining input function for new datatype

Defining input function for new datatype

From
Nick Raj
Date:
Hi,
I am defining a new data type called mpoint
i.e.
typedef struct mpoint
{
    Point p;
    Timestamp t;
} mpoint;

For defining input/output function

1     Datum mpoint_in(PG_FUNCTION_ARGS)
2     {
3
4        mpoint *result;
5        char *pnt=(char *)malloc (sizeof (20));
6        char *ts=(char *)malloc (sizeof (20));
7        result= (mpoint *) palloc(sizeof(mpoint));
8        char *st = PG_GETARG_CSTRING(0);
9        mpoint_decode(st,pnt,ts);                                         // st breaks down into pnt that corresponds to Point and ts corresponds to Timestamp
10   
11      result->p = point_in(PointerGetDatum(pnt));                // point_in (input function for point that assigns x, y into point)
12      result-> t = timestamp_in(PointerGetDatum(ts));         // similar for timestamp
13  
14      PG_RETURN_MPOINT_P(result);
15   }

line no 11 warning: passing argument 1 of ‘point_in’ makes pointer from integer without a cast
                     ../../../include/utils/geo_decls.h:191: note: expected ‘FunctionCallInfo’ but argument is of type ‘unsigned int’
line no 11 error: incompatible types when assigning to type ‘Point’ from type ‘Datum’
line no 12 warning: passing argument 1 of ‘timestamp_in’ makes pointer from integer without a cast
                     ../../../include/utils/timestamp.h:205: note: expected ‘FunctionCallInfo’ but argument is of type ‘unsigned int’

Can anybody figure out what kind of mistake i am doing?
Also, why it got related to 'FunctionCallInfo' ?

Thanks
Nick

Re: [HACKERS] Defining input function for new datatype

From
Pavel Stehule
Date:
Hello

2011/4/21 Nick Raj <nickrajjain@gmail.com>:
> Hi,
> I am defining a new data type called mpoint
> i.e.
> typedef struct mpoint
> {
>     Point p;
>     Timestamp t;
> } mpoint;
>
> For defining input/output function
>
> 1     Datum mpoint_in(PG_FUNCTION_ARGS)
> 2     {
> 3
> 4        mpoint *result;
> 5        char *pnt=(char *)malloc (sizeof (20));
> 6        char *ts=(char *)malloc (sizeof (20));
> 7        result= (mpoint *) palloc(sizeof(mpoint));
> 8        char *st = PG_GETARG_CSTRING(0);
> 9        mpoint_decode(st,pnt,ts);
> // st breaks down into pnt that corresponds to Point and ts corresponds to
> Timestamp
> 10
> 11      result->p = point_in(PointerGetDatum(pnt));                //
> point_in (input function for point that assigns x, y into point)
> 12      result-> t = timestamp_in(PointerGetDatum(ts));         // similar
> for timestamp
> 13
> 14      PG_RETURN_MPOINT_P(result);
> 15   }
>
> line no 11 warning: passing argument 1 of ‘point_in’ makes pointer from
> integer without a cast
>                      ../../../include/utils/geo_decls.h:191: note: expected
> ‘FunctionCallInfo’ but argument is of type ‘unsigned int’
> line no 11 error: incompatible types when assigning to type ‘Point’ from
> type ‘Datum’
> line no 12 warning: passing argument 1 of ‘timestamp_in’ makes pointer from
> integer without a cast
>                      ../../../include/utils/timestamp.h:205: note: expected
> ‘FunctionCallInfo’ but argument is of type ‘unsigned int’
>

you are missing a important header files.

> Can anybody figure out what kind of mistake i am doing?
> Also, why it got related to 'FunctionCallInfo' ?

see on definition of PG_FUNCTION_ARGS macro

Regards

Pavel Stehule

>
> Thanks
> Nick
>

Re: Defining input function for new datatype

From
Tom Lane
Date:
Nick Raj <nickrajjain@gmail.com> writes:
> 1     Datum mpoint_in(PG_FUNCTION_ARGS)
> 2     {
> 3
> 4        mpoint *result;
> 5        char *pnt=(char *)malloc (sizeof (20));
> 6        char *ts=(char *)malloc (sizeof (20));

(1) You should *not* use malloc here.  There is seldom any reason to use
malloc directly at all in functions coded for Postgres.  Use palloc,
or expect memory leaks.

(2) sizeof(20) almost certainly doesn't mean what you want.  It's most
likely 4 ...

> 11      result->p = point_in(PointerGetDatum(pnt));                //
> point_in (input function for point that assigns x, y into point)

You need to use DirectFunctionCallN when trying to call a function that
obeys the PG_FUNCTION_ARGS convention, as point_in does.  And the result
is a Datum, which means you're going to need to apply a DatumGetWhatever
macro to get a bare Point or Timestamp from these functions.

Look around in the PG sources for examples.

            regards, tom lane