Re: Better support for whole-row operations and composite - Mailing list pgsql-hackers

From Joe Conway
Subject Re: Better support for whole-row operations and composite
Date
Msg-id 406F1391.9090006@joeconway.com
Whole thread Raw
In response to Re: Better support for whole-row operations and composite types  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Better support for whole-row operations and composite
Re: Better support for whole-row operations and composite types
List pgsql-hackers
Tom Lane wrote:
> No, it's a HeapTupleHeader pointer.  You need to reconstruct a
> HeapTuple on top of that to work with heap_getattr and most other
> core backend routines.

Thanks.

For triggers, I was previously building up the arguments thus:
    slot = TupleDescGetSlot(tupdesc);    slot->val = trigdata->tg_trigtuple;    arg[7] = PointerGetDatum(slot);

I suppose now I should do this instead?
    arg[7] = PointerGetDatum(trigdata->tg_trigtuple->t_data);


> Also don't forget to ensure that you detoast the datum; this is not
> useful at the moment but will be important Real Soon Now. I added
> standard argument-fetch macros to fmgr.h to help with the detoasting
> bit.

OK. This is the net result:

#ifdef PG_VERSION_75_COMPAT  Oid               tupType;  int32             tupTypmod;  TupleDesc         tupdesc;
HeapTuple        tuple = palloc(sizeof(HeapTupleData));  HeapTupleHeader   tuple_hdr =
DatumGetHeapTupleHeader(arg[i]);
  tupType = HeapTupleHeaderGetTypeId(tuple_hdr);  tupTypmod = HeapTupleHeaderGetTypMod(tuple_hdr);  tupdesc =
lookup_rowtype_tupdesc(tupType,tupTypmod);
 
  tuple->t_len = HeapTupleHeaderGetDatumLength(tuple_hdr);  ItemPointerSetInvalid(&(tuple->t_self));  tuple->t_tableOid
=InvalidOid;  tuple->t_data = tuple_hdr;
 
  PROTECT(el = pg_tuple_get_r_frame(1, &tuple, tupdesc));
  pfree(tuple);
#else  TupleTableSlot *slot = (TupleTableSlot *) arg[i];  HeapTuple       tuple = slot->val;  TupleDesc       tupdesc =
slot->ttc_tupleDescriptor;
  PROTECT(el = pg_tuple_get_r_frame(1, &tuple, tupdesc));
#endif /* PG_VERSION_75_COMPAT */


Given the above changes, it's almost working now -- only problem left is 
with triggers:

  insert into foo values(11,'cat99',1.89);
+ ERROR:  record type has not been registered
+ CONTEXT:  In PL/R function rejectfoo
  delete from foo;
+ ERROR:  cache lookup failed for type 0
+ CONTEXT:  In PL/R function rejectfoo

(and a few other similar failures)

Any ideas why the trigger tuple type isn't registered, or what I'm doing 
wrong?

Thanks,

Joe


pgsql-hackers by date:

Previous
From: Greg Stark
Date:
Subject: Re: Inconsistent behavior on Array & Is Null?
Next
From: Joe Conway
Date:
Subject: Re: Inconsistent behavior on Array & Is Null?