From: | Ron Peterson <ron(dot)peterson(at)yellowbank(dot)com> |
---|---|
To: | Gregory Stark <stark(at)enterprisedb(dot)com> |
Cc: | pgsql-general(at)postgresql(dot)org |
Subject: | Re: convert binary string to datum |
Date: | 2007-10-13 12:50:56 |
Message-ID: | 20071013125056.GC5729@yellowbank.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
2007-10-13_01:22:06-0400 Gregory Stark <stark(at)enterprisedb(dot)com>:
> "Ron Peterson" <ron(dot)peterson(at)yellowbank(dot)com> 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/
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2007-10-13 13:59:19 | Re: contrib / fuzzystr documentation |
Previous Message | Trevor Talbot | 2007-10-13 08:21:42 | Re: can I define own variables? |