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: Alban Hertroys <dalroi(at)solfertje(dot)student(dot)utwente(dot)nl>
Cc: Greg Stark <gsstark(at)mit(dot)edu>, postgres list <pgsql-general(at)postgresql(dot)org>
Subject: Re: Tagged types module and varlena changes
Date: 2009-08-26 15:13:13
Message-ID: 64126AD6-89FA-4638-A3FC-71B22D69F167@solfertje.student.utwente.nl (view raw or flat)
Thread:
Lists: pgsql-general
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!



In response to

pgsql-general by date

Next:From: Alvaro HerreraDate: 2009-08-26 15:17:06
Subject: Re: ETL software and training
Previous:From: Fred JanonDate: 2009-08-26 15:08:52
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