Re: understanding Datum -> char * -> Datum conversions

From: Louis-David Mitterrand <cunctator(at)apartia(dot)ch>
To: Karel Zak <zakkr(at)zf(dot)jcu(dot)cz>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: understanding Datum -> char * -> Datum conversions
Date: 2000-05-25 09:53:54
Message-ID: 20000525115354.B10653@styx
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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(at)apartia(dot)org - http://www.apartia.fr

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Karel Zak 2000-05-25 10:03:55 Re: understanding Datum -> char * -> Datum conversions
Previous Message Zeugswetter Andreas SB 2000-05-25 09:44:24 AW: SQL3 UNDER