문제

Postgresql 9.1.0. OS Ubuntu 11.10. Compiler gcc 4.6.1

Here is my table:

CREATE TABLE ttest
(
  x integer,
  str text
 )
 WITH (
 OIDS=FALSE
);
ALTER TABLE ttest OWNER TO postgres;

CREATE TRIGGER tb
BEFORE INSERT
ON ttest
FOR EACH ROW
EXECUTE PROCEDURE out_trig();

out_trig is C functcion.

Now im trying to get data from each row being inserted. Here is the code:

if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
{
    rettuple = trigdata->tg_trigtuple;
    bool isnull = false;
    uint32 x=rettuple->t_len;
    int64 f;
        f = (int64) GetAttributeByNum(rettuple->t_data, 1, &isnull);//error here
    elog(INFO,"len of tuple: %d",x);
    elog(INFO,"first column being inserted x: %d",f);
 }

I got ERROR: record type has not been registered

SQL state: 42809

What am I doing wrong and how to do it correctly?

도움이 되었습니까?

해결책

GetAttributeByNum (or GetAttributeByName) only works with Datums, not on-disk tuples, use heap_getattr instead.

You've declared x as integer but trying to read it as int64 (PostgreSQL uses int4 for integer types unless you explicitly specify your column as int8).

Last but not least, use DatumGet[YourType] macros when calling functions that return Datums, converting the value directly to the desired type breaks portability.

Long and short, the code should becomes something like this:

if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
{
    HeapTuple rettuple = trigdata->tg_trigtuple;
    TupleDesc tupdesc = trigdata->tg_relation->rd_att;
    bool isnull = false;
    uint32 x=rettuple->t_len;
    int32 att = DatumGetInt32(heap_getattr(rettuple, 1, tupdesc, &isnull));
    elog(INFO,"len of tuple: %d",x);
    if (!isnull)
        elog(INFO,"first column being inserted x: %d",att);
    else
        elog(INFO,"first column being inserted x: NULL"); 
 }

You might also want to take a look at SPI interface, which simplifies access to the database from user-defined C functions: http://www.postgresql.org/docs/current/interactive/spi.html

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top