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