Обсуждение: C Tigger Function Tuples

Поиск
Список
Период
Сортировка

C Tigger Function Tuples

От
"Kubat, Philip"
Дата:
I am creating a C function which send inserted records to a file called via a after insert trigger. I have attached my code. I have the basic functionality working, but I need to understand working with heap tuples.  I am using heap_getattr to retrieve the attrs from the HeapTuple.  I am planning to loop through the attr and the send then to a file. 
 
My question is how do you know what "type" an attr is?  To convert from Datum to C type i.e. DataGetInt32, dataGetCString, etc.  (See my dummy function GetDatumType.)
 
Thanks!
Philip Kubat
 

/*
 Echos new record to file
*/
#include <stdlib.h>
#include "executor/spi.h" /* this is what you need to work with SPI */ #include "commands/trigger.h" /* -"- and triggers */

// Dummy prototype for function, looking for the real thing!
int GetDatumType(Datum myDatum);

extern Datum cbe_echo(PG_FUNCTION_ARGS);

PG_FUNCTION_INFO_V1(echo_echo);

Datum cbe_echo(PG_FUNCTION_ARGS)
{
 TriggerData *trigdata = (TriggerData *) fcinfo->context;
 TupleDesc tupdesc;
 HeapTuple rettuple;
 bool isnull;
 char* str;
 int num;

 int numatts;
 int curattr;
 Datum retDatum;

 /* Make sure trigdata is pointing at what I expect */
 if (!CALLED_AS_TRIGGER(fcinfo))
  elog(ERROR, "pg_echo: not fired by trigger manager");
 
 elog(DEBUG,"cbe_echo: function called");

 /* tuple to return to Executor */
 if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
  rettuple = trigdata->tg_newtuple;
 else
  rettuple = trigdata->tg_trigtuple;
 
 tupdesc = trigdata->tg_relation->rd_att;

/*
 //str=(char*)palloc(40);
 //str = (char*) GetAttributeByName(rettuple->t_data, "name", &isnull);

        str=(char*)DatumGetCString(DirectFunctionCall1(textout,heap_getattr(rettuple,1,tupdesc,&isnull)));
        num=DatumGetInt32(heap_getattr(rettuple,2,tupdesc,&isnull));
 if (isnull)
  elog(DEBUG,"cbe_echo: NULL");
 else
  elog(DEBUG,"cbe_echo: not NULL");


 elog(DEBUG,"cbe_echo: output..");
 elog(DEBUG,"cbe_echo: num <%i> str <%s>",num,str);
 elog(DEBUG,"cbe_echo: t_data t_natts <%i>",rettuple->t_data->t_natts);
 elog(DEBUG,"cbe_echo: tuple lenght %i",rettuple->t_len);
 elog(DEBUG,"cbe_echo: end.");
*/
 
 // Sample of what I would like to do.

 numatts=rettuple->t_data->t_natts;

 for ( curattr=1;curattr<=numatts;curattr++ ) {
      retDatum=heap_getattr(rettuple,curattr,tupdesc,&isnull);

  // ** WHAT IS THIS FUNTION ** //
  switch (GetDatumType(retDatum)) {

   // int4 type oid?
   case 23: elog(DEBUG,"cbe_echo: %i",DatumGetInt32(heap_getattr(rettuple,2,tupdesc,&isnull)));
   break;

   // text?
   case 25: elog(DEBUG,"cbe_echo: %s",(char*)DatumGetCString(
    DirectFunctionCall1(textout,heap_getattr(rettuple,1,tupdesc,&isnull))));
   break;
  } //switch
 } //for

 return PointerGetDatum(rettuple);
}

Re: C Tigger Function Tuples

От
Joe Conway
Дата:
Kubat, Philip wrote:
> I am creating a C function which send inserted records to a file called
> via a after insert trigger. I have attached my code. I have the basic
> functionality working, but I need to understand working with heap
> tuples.  I am using heap_getattr to retrieve the attrs from the
> HeapTuple.  I am planning to loop through the attr and the send then to
> a file.
>
> My question is how do you know what "type" an attr is?  To convert from
> Datum to C type i.e. DataGetInt32, dataGetCString, etc.  (See my dummy
> function GetDatumType.)

Without looking too closely at your code, it sounds like you want to use
the "out" function for each attribute's data type to produce a C-string
representation of it?

Look in execTuples.c and funcapi.c (in CVS, not in 7.2.1) at
TupleDescGetAttInMetadata(), BuildTupleFromCStrings(), and
get_type_metadata() for an example of just the opposite process --
building a tuple from C strings. You should be able to do something
similar with the "out" functions instead of the "in" functions.

I'm sure there are other examples that can be found in the source.
Another likely place to look is the code in copy.c.

HTH,

Joe