I still have the same problem. Whatever I've tried didn't work out.
It seems like VARSIZE is wrong. It's less than it should be. It seems like it's 
not counting on the size of units array, although it changes depending on the 
number of units.
This is one of the things I've tried:

Datum mbool_in(PG_FUNCTION_ARGS)
{
    char *str = PG_GETARG_CSTRING(0);
    mBool *result;
        mBool *finalResult;
        int size;

    result = (mBool *) create_mConst(str, MBOOL);

        size = sizeof(int4) + sizeof(int) + result->noOfUnits*sizeof(uBool);
        finalResult = (mBool *) palloc(size);
        memcpy(finalResult, result, size);
        SET_VARSIZE(finalResult, size);
    
    PG_RETURN_POINTER(finalResult);
}

Datum mbool_out(PG_FUNCTION_ARGS)
{
    mBool * input = (mBool *) PG_GETARG_POINTER(0);
        mBool * safeCopy;
    char * result;

        safeCopy = (mBool *) palloc(VARSIZE(input));
        SET_VARSIZE(safeCopy, VARSIZE(input));
        memcpy((void *) VARDATA(safeCopy),
               (void *) VARDATA(input),
                VARSIZE(input));
    
    result = ToString (safeCopy, MBOOL);
    
    PG_RETURN_CSTRING(result);
}

How to fix this? The one who helps can count on the best Croatian dark beer 
shipped directly to his place. ;)

Ivan


From: i....@live.com
To: t...@sss.pgh.pa.us
CC: klep...@svana.org; dal...@solfertje.student.utwente.nl; 
pgsql-general@postgresql.org
Subject: RE: [GENERAL] Persistence problem
Date: Fri, 14 May 2010 14:35:34 +0200








Thanks for the reply.
Why is that somewhere else in the memory if I reserve enough memory with palloc 
and copy the complete memory from the previously created type into that new 
object?

realResult = (mPoint *)palloc(result->length);
memcpy(realResult, result, result->length);

OK, I suppose I should use the VARDATA and VARSIZE. But I really can't make it 
to work. I don't think I understood well enough how it works. This is what I'd 
like to do. I would like to create the type as I already did, and when it's 
created I would like to copy its memory into a new object. So, if I have:

Datum mpoint_in(PG_FUNCTION_ARGS)
{
    char *str = PG_GETARG_CSTRING(0);
    mPoint *result = (mPoint *) create_mPoint(str);

    mPoint *final result = ... //copy the memory from result

    PG_RETURN_POINTER(result);
}

Datum mpoint_out(PG_FUNCTION_ARGS)
{
    mPoint * input = (mPoint *) PG_GETARG_POINTER(0);
    char * result = ToString (input, MPOINT);    
    PG_RETURN_CSTRING(result);
}

Can you please help me to make this? How to copy the memory in a good way? 
Should I somehow change the type mPoint? Should I also change the SQL side?

CREATE TYPE mpoint (
   internallength = VARIABLE,
   input = mpoint_in,
   output = mpoint_out
);

Please help, it would mean a lot.

Thanks,
Ivan


> To: i....@live.com
> CC: klep...@svana.org; dal...@solfertje.student.utwente.nl; 
> pgsql-general@postgresql.org
> Subject: Re: [GENERAL] Persistence problem 
> Date: Thu, 13 May 2010 15:08:58 -0400
> From: t...@sss.pgh.pa.us
> 
> "I. B." <i....@live.com> writes:
> > When I do this:
> >     realResult = (mPoint *)palloc(result->length);
> >     memcpy(realResult, result, result->length);
> > I get a right result in the same session, but corrupted in the next
> > one.
> 
> I'm guessing a bit here, but I think what is happening is this:
> 
> > typedef struct {
> >     int4 length;
> >     int noOfUnits;
> >     void *units; // this is later casted to uPoint *
> > } mapping_t;
> 
> You're storing the above-named struct on disk, right?  And the "units"
> pointer is pointing to an array that's somewhere else in memory?  As
> long as the somewhere-else array survives, it will seem like everything
> is okay.  But in a new session, that data in memory will certainly not
> be there anymore.
> 
> You can't use pointers in data structures that are to be stored on disk.
> The array data needs to be "in line" in the data structure, and
> accounted for in the length word.
> 
> Martin's advice about using VARSIZE/VARDATA is good too.  Depending on
> which PG version you're using, you might be able to get along without
> that so long as you haven't marked the data type toastable (by using
> a non-PLAIN storage option in CREATE TYPE).  But unless that array is
> always pretty darn small, you're going to want to allow this type to
> be toasted.
> 
>                       regards, tom lane
                                          
Hotmail: Trusted email with Microsoft’s powerful SPAM protection. Sign up now.  
                                  
_________________________________________________________________
Hotmail: Trusted email with powerful SPAM protection.
https://signup.live.com/signup.aspx?id=60969

Reply via email to