On 26 Aug 2009, at 16:55, Alban Hertroys wrote:
With the SET_VARSIZE the above should work *as long as datum is not
toasted (or packed)*. If it's been detoasted then that's good, or if
it was freshly generated and not stored in a tuple then it should be
good too.
I changed it to:
struct varlena* tv = (struct
varlena*)tt_palloc( VARSIZE( datum ) );
struct taggedtypev *typev =
(struct taggedtypev*) DatumGetPointer( datum );
int a = VARSIZE(datum) - sizeof(Oid),
b = VARSIZE_ANY_EXHDR(datum) - sizeof(Oid);
SET_VARSIZE(tv->vl_len_, a);
memcpy( tv->vl_dat, &typev->val, b );
return PointerGetDatum( tv ) ;
But still I get a segfault on the memcpy line. The backtrace shows
the following (line 0 is the memcpy itself, nothing useful to see
there):
#1 0x29806f74 in ExtractTaggedTypeDatum (tti=0x2980c560,
datum=726659176)
at taggedtypes.c:249
249 memcpy( tv->vl_dat, &typev->val, b );
(gdb) print *tv
$1 = {vl_len_ = "\000\000\000", vl_dat = ""}
(gdb) print a
$2 = 0
(gdb) print b
$3 = -4
(gdb) print *typev
$4 = {len = "\020\000\000", tag = 68899, val = "!\000\000"}
Obviously passing a negative value as the size to copy is what's
causing the segfault, but how come it's negative? Could it be that
my table doesn't have Oid's and that subtracting sizeof(Oid) is what
makes the length become negative?
To follow up on this:
One of the failing queries is:
select * from taggedtypes.currency_test ;
development=# \d+ taggedtypes.currency_test
Table "taggedtypes.currency_test"
Column | Type | Modifiers | Description
--------+---------------------------+-----------+-------------
c1 | taggedtypes.currency | |
c2 | taggedtypes.currencyint | |
c3 | taggedtypes.currencyfloat | |
Has OIDs: no
I changed the test script to create the table WITH OIDS, and now the
code works!
Is there some way to check whether a Datum is from a table with OIDs?
I think the code could do with a check for that and error out if the
table doesn't have those...
Alban Hertroys
--
Screwing up is the correct approach to attaching something to the
ceiling.
!DSPAM:737,4a95510b11861909511901!
--
Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general