Skip site navigation (1) Skip section navigation (2)

Re: Tagged types module and varlena changes

From: Alban Hertroys <dalroi(at)solfertje(dot)student(dot)utwente(dot)nl>
To: Greg Stark <gsstark(at)mit(dot)edu>
Cc: postgres list <pgsql-general(at)postgresql(dot)org>
Subject: Re: Tagged types module and varlena changes
Date: 2009-08-26 14:55:18
Message-ID: 21AD48CF-1868-4632-BC7C-B1B03A27ABEF@solfertje.student.utwente.nl (view raw or flat)
Thread:
Lists: pgsql-general
On 26 Aug 2009, at 15:33, Greg Stark wrote:

> On Wed, Aug 26, 2009 at 1:14 PM, Alban
> Hertroys<dalroi(at)solfertje(dot)student(dot)utwente(dot)nl> wrote:
>>> struct varlena* tv = (struct varlena*)tt_palloc( VARSIZE( datum ) );
>>>
>>> tv->vl_len = VARSIZE( datum ) - sizeof(Oid);
>>> memcpy( tv->vl_dat,
>>>        &((struct taggedtypev*)DatumGetPointer( datum ))->val,
>>>        VARSIZE(datum) - sizeof(Oid) - VARHDRSZ );
>>> return PointerGetDatum( tv ) ;
>>
>>
>> This doesn't compile anymore as the vl_len member of struct varlena  
>> no
>> longer exists and we're supposed to use the SET_VARSIZE macro  
>> instead now.. I
>> tried that, but then the memcpy bails out due to the size  
>> calculation being
>> wrong. I don't know enough about varlena usage to figure out what the
>> correct way of calculating the size for memcpy is, or whether that  
>> approach
>> is at all feasable with the current varlena implementation. What  
>> should the
>> above read?
>>
>
> 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?

I did some reading up on TOASTing and how to use those macro's, but  
the manual wasn't very detailed in this particular area... I doubt my  
values are TOASTed though, they're rather short values; not quite 2k  
anyway.

Alban Hertroys

--
If you can't see the forest for the trees,
cut the trees and you'll see there is no forest.


!DSPAM:737,4a954cda11869014116556!



In response to

Responses

pgsql-general by date

Next:From: Fred JanonDate: 2009-08-26 15:08:52
Subject: Re: How to create a multi-column index with 2 dates using 'gist'?
Previous:From: Gerhard HeiftDate: 2009-08-26 14:26:13
Subject: Re: How to create a multi-column index with 2 dates using 'gist'?

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group