Обсуждение: Implementing an operator in C?

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

Implementing an operator in C?

От
Mario Weilguni
Дата:
Sorry if I'm posting to the wrong list, if so, please could you point me to 
the correct list? Thanks!

I'm trying to work with Access and Postgres as backend, but I often get 
errors like "unable to find an operator '=' for numeric and float" and 
such. Now I've implemented an operator in PLPGSQL, but I'm not very 
satisfied with the results (performance-wise). I've tried it in C, but 
failed:

I've written a function like this one (I tried to copy the behaviour a 
compersion function in utils/adt/numeric.c):

Datum
numeric_float8_eq(PG_FUNCTION_ARGS)
{       Numeric         num1 = PG_GETARG_NUMERIC(0);       float8          num2 = PG_GETARG_FLOAT8(1);       bool
    result;
 
       if (NUMERIC_IS_NAN(num1) || isnan(num2))               result = false;       else       {         float8 num3 =
numeric_float8(num1);        if(num2 == num3)           result = true;         else           result = false;       }
 
       PG_FREE_IF_COPY(num1, 0);
       PG_RETURN_BOOL(result);
}

Unfortunatly, this fails. The backend dies with a SIGNAL11 when calling 
this functions. Are there any examples how to implement such operators (any 
example might help)?

Thanks!

Best regards,       Mario Weilguni



Re: Implementing an operator in C?

От
Tom Lane
Дата:
Mario Weilguni <mweilguni@sime.com> writes:
>           float8 num3 = numeric_float8(num1);

That won't work in the brave new world of 7.1 :-(.  You need to do
something like
float8 num3 = DatumGetFloat8(DirectFunctionCall1(numeric_float8,                NumericGetDatum(num1)));

Ugly, I know ... but we have to be rigidly careful about converting
values to Datum and back in order to avoid portability problems.

A decent C compiler should've warned about type mismatches in your call,
BTW.
        regards, tom lane


Re: Implementing an operator in C?

От
Mario Weilguni
Дата:
Am Sonntag,  4. Februar 2001 20:12 schrieben Sie:
> Mario Weilguni <mweilguni@sime.com> writes:
> >           float8 num3 = numeric_float8(num1);
>
> That won't work in the brave new world of 7.1 :-(.  You need to do
> something like
>
>     float8 num3 = DatumGetFloat8(DirectFunctionCall1(numeric_float8,
>                     NumericGetDatum(num1)));
>
> Ugly, I know ... but we have to be rigidly careful about converting
> values to Datum and back in order to avoid portability problems.
>
> A decent C compiler should've warned about type mismatches in your call,
> BTW.
>
>             regards, tom lane

Thanks alot for the info, but the problem is elsewhere. Even a simple 
function like
Datum
nef(PG_FUNCTION_ARGS)
{
         Numeric                 num1 = PG_GETARG_NUMERIC(0);
         PG_RETURN_BOOL(true);
}

will crash. The macro PG_GETARG_NUMERIC evaluates to:
((Numeric)pg_detoast_datum((struct varlena *) ((Pointer) ( (fcinfo->arg[0])))
and this pg_detoast_datum will lead to a crash (SIGSEGV). So I think I must 
be doing something wrong here, isn't it?

Thanks!

Best regards,
         Mario Weilguni

-- 
===================================================Mario Weilguni                               KPNQwest Austria GmbH
 Senior Engineer Web Solutions                         Nikolaiplatz 4
 tel: +43-316-813824                                8020 graz, austria
 fax: +43-316-813824-26                    http://www.kpnqwest.at
 e-mail: mario.weilguni@kpnqwest.com
===================================================



Re: Implementing an operator in C?

От
Thomas Lockhart
Дата:
Mario Weilguni wrote:
> 
> Am Sonntag,  4. Februar 2001 20:12 schrieben Sie:
> > Mario Weilguni <mweilguni@sime.com> writes:
> > >           float8 num3 = numeric_float8(num1);
> >
> > That won't work in the brave new world of 7.1 :-(.  You need to do
> > something like
> >
> >       float8 num3 = DatumGetFloat8(DirectFunctionCall1(numeric_float8,
> >                                       NumericGetDatum(num1)));
> >
> > Ugly, I know ... but we have to be rigidly careful about converting
> > values to Datum and back in order to avoid portability problems.
> >
> > A decent C compiler should've warned about type mismatches in your call,
> > BTW.
> >
> >                       regards, tom lane
> 
> Thanks alot for the info, but the problem is elsewhere. Even a simple
> function like
> Datum
> nef(PG_FUNCTION_ARGS)
> {
>          Numeric                 num1 = PG_GETARG_NUMERIC(0);
>          PG_RETURN_BOOL(true);
> }
> 
> will crash. The macro PG_GETARG_NUMERIC evaluates to:
> ((Numeric)pg_detoast_datum((struct varlena *) ((Pointer) ( (fcinfo->arg[0])))
> and this pg_detoast_datum will lead to a crash (SIGSEGV). So I think I must
> be doing something wrong here, isn't it?

Could be. What data type *is* the input argument? It had better be of
type "NUMERIC", and not of type "FLOAT8", which of course uses a
different accessor function...
                    - Thomas