2007-10-13_01:22:06-0400 Gregory Stark <stark@xxxxxxxxxxxxxxxx>: > "Ron Peterson" <ron.peterson@xxxxxxxxxxxxxx> writes: > > > Is this a legitimate/blessed way to go about it? > > > > aval = (bytea *)palloc( len + VARHDRSZ ); > > VARATT_SIZEP(aval) = len + VARHDRSZ; > > memcpy( VARDATA(aval), myrawdata, len ); > > values[0] = PointerGetDatum(aval); > > ...etc > > tuple = heap_formtuple( tupdesc, values, &isNull ); > > Yes, assuming that your tuple descriptor there does in fact have a varlena > data type in column 1. I think that's the part I'm missing. I'm doing: if( get_call_result_type( fcinfo, NULL, &tupdesc ) != TYPEFUNC_COMPOSITE ) ereport( ERROR, ( errcode( ERRCODE_FEATURE_NOT_SUPPORTED ), errmsg( "function returning record called in context " "that cannot accept type record" ))); BlessTupleDesc( tupdesc ); I'm not doing anything explicit to set a varlena datatype in column 1. How would I do that? > And normally you would define your own datatype and not use bytea. Actually, I already have my data in a structure much like varlena. I see PointerGetDatum basically just casts it's argument to (Datum), which is ultimately defined as an unsigned long, I believe. I'm not understanding the magic that PostgreSQL uses to understand whether this is a value or a reference, and whether it's fixed or variable length though. That must be what the tupledesc does, but I don't think I'm setting that up right. I think. Maybe. -Ron- Personally I'm not entirely clear why we don't just use void* for > text and bytea though. > > Postgres 8.3 has a different macro api here though. If you want to > future-proof your code you could do (put the macro definition somewhere in > your private header file after including postgres.h). > > #ifndef SET_VARSIZE > #define SET_VARSIZE(v,l) (VARATT_SIZEP(v) = (l)) > #endif > > aval = (bytea *)palloc( len + VARHDRSZ ); > SET_VARSIZE(aval, len + VARHDRSZ); > memcpy( VARDATA(aval), myrawdata, len ); > values[0] = PointerGetDatum(aval); > ...etc > tuple = heap_formtuple( tupdesc, values, &isNull ); > > Also, make sure you use VARSIZE to refer to the size header at all times, > don't refer to it directly. And unless you mark it with storage plain always > detoast it before working with an argument or anything from heap_deform_tuple. > In postgres we normally put pg_detoast_datum() directly into the DatumGetFoo() > and PG_GETARG_FOO_P() macros. > > > -- > Gregory Stark > EnterpriseDB http://www.enterprisedb.com -- Ron Peterson https://www.yellowbank.com/ ---------------------------(end of broadcast)--------------------------- TIP 6: explain analyze is your friend