Thread: 38.10.6. Composite-Type Arguments C-language function code demo works for int, but not for numeric.




Hi.

column "salary" int data type works fine. But it does not work if the "salary" column data type is numeric.

/*
rm funcs.so && rm funcs.o
gcc -I/home/jian/postgres/pg16/include/postgresql/server -fPIC -c funcs.c
gcc -shared -o funcs.so funcs.o
*/

#include "postgres.h"
#include "executor/executor.h"
#include  "utils/numeric.h"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(c_overaid);

Datum
c_overaid(PG_FUNCTION_ARGS)
{
    HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(0);
    Numeric           limit = PG_GETARG_NUMERIC_COPY(1);
    bool isnull;
    Datum   salary;

    salary = GetAttributeByName(t,"salary",&isnull);
    if(isnull)
        PG_RETURN_BOOL(false);

    /* alternatively, we might prefer to do PG_RETURN_NULL() for null salary */
    PG_RETURN_BOOL(DatumGetNumericCopy(salary) > limit);
}
---------------------------------------------------------------------------
then quit the session and reconnect the session.

drop table emp cascade;
create table emp(empid bigint, salary numeric, name text);
insert into emp values(1,1000,'a1');
insert into emp values(2,1100,'a2');
insert into emp values(3,1200,'a3');
CREATE OR REPLACE FUNCTION c_overaid(emp, numeric) returns boolean AS '/home/jian/pg_ext/misc/funcs','c_overaid' LANGUAGE C STRICT;
select name, c_overaid(emp,numeric '1110') as over_paid from emp;
it returns
 name | over_paid
------+-----------
 a1   | t
 a2   | t
 a3   | t
(3 rows)

I also tried PG_GETARG_NUMERIC,DatumGetNumeric(salary).



jian he <jian.universality@gmail.com> writes:
> column "salary" int data type works fine. But it does not work if the
> "salary" column data type is numeric.

Your problem is that numeric is not a primitive C type:

>     PG_RETURN_BOOL(DatumGetNumericCopy(salary) > limit);

That is comparing two pointers-to-numerics, not the values of
the numerics.  You'd need to invoke numeric_cmp() if you
want a sensible result.

            regards, tom lane