Implementing an operator in C?

Started by Mario Weilguniabout 25 years ago4 messageshackers
Jump to latest
#1Mario Weilguni
mweilguni@sime.com

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

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Mario Weilguni (#1)
Re: Implementing an operator in C?

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

#3Mario Weilguni
Mario.Weilguni@kpnqwest.com
In reply to: Tom Lane (#2)
Re: Implementing an operator in C?

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

#4Thomas Lockhart
lockhart@alumni.caltech.edu
In reply to: Mario Weilguni (#1)
Re: Implementing an operator in C?

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