Re: understanding Datum -> char * -> Datum conversions - Mailing list pgsql-hackers

From Louis-David Mitterrand
Subject Re: understanding Datum -> char * -> Datum conversions
Date
Msg-id 20000525115354.B10653@styx
Whole thread Raw
In response to Re: understanding Datum -> char * -> Datum conversions  (Karel Zak <zakkr@zf.jcu.cz>)
Responses Re: understanding Datum -> char * -> Datum conversions  (Karel Zak <zakkr@zf.jcu.cz>)
List pgsql-hackers
On Wed, May 24, 2000 at 06:34:48PM +0200, Karel Zak wrote:
> > 
> > Also I am trying to read a timestamp with SPI_getbinval and get the
> > number of seconds contained. Using DatumGetInt32 doens't seem to do it.
> 
> Examples:
>  
> * Add actual time to column "chtime": 
>  
>           Datum   chtime  = PointerGetDatum(timestamp_in("now"));
>           int     attnum  = SPI_fnumber(tupdesc, "chtime");
> 
>           rettuple = SPI_modifytuple(CurrentTriggerData->tg_relation,
>                       rettuple, 1, &attnum, &chtime, NULL);

Thanks for your example, the timestamp_in() function is really useful.
But how should I do it if I want to:
1) retrieve a timestamp Datum,
2) add a few days to it,
3) store it back in the tuple,

The problem is converting the Datum to a base C type in order to be able
to modify it.

in pgsql/contrib/spi/timetravel.c there is an example which modifies
date columns and uses DatumGetInt32 to convert them. But this is
confusing because (1) Tom Lane says that datetime columns are double and
one should use DatumGetPointer (how do I use the pointer after?) and (2)
DatumGetInt32 doesn't seem to return the number of seconds.

>  You can use instead "now" SPI_getvalue() .... etc.
> 
> * A small complex example:
> 
> HeapTuple xxx_trigger()
> {
>         TupleDesc       tupdesc;
>         HeapTuple       rettuple        = NULL;
>     int         attnum;
>     char        *value;
>     Datum       newdt;
> 
>         if (!CurrentTriggerData)
>                 elog(ERROR, "XXX: triggers are not initialized");
> 
>         if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) {
>                 rettuple = CurrentTriggerData->tg_newtuple;
>         else if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event)) 
>                 rettuple = CurrentTriggerData->tg_trigtuple;
>         else if (TRIGGER_FIRED_BY_DELETE(CurrentTriggerData->tg_event)) 
>                 rettuple = CurrentTriggerData->tg_trigtuple;
>         
>     tupdesc = CurrentTriggerData->tg_relation->rd_att;
> 
>     if ( SPI_connect() < 0)                
>                 elog(ERROR, "SPI_connect() fail... ");
> 
>     attnum    = SPI_fnumber(tupdesc, "ColumnName");
>      value    = SPI_getvalue(rettuple, tupdesc, attnum);

But you get a char * value here through SPI_getvalue()?

>     /* --- add some code for 'value' ---*/
> 
>     newdt    = PointerGetDatum(value);

This is enough to convert the char * back to a Datum?

>      rettuple = SPI_modifytuple(CurrentTriggerData->tg_relation,
> 
>  .......... it must works :-)

Thanks for your examples, I'm slowly beginning to understand...

-- 
Louis-David Mitterrand - ldm@apartia.org - http://www.apartia.fr


pgsql-hackers by date:

Previous
From: Zeugswetter Andreas SB
Date:
Subject: AW: SQL3 UNDER
Next
From: Zeugswetter Andreas SB
Date:
Subject: AW: AW: Postgresql OO Patch