Re: Persistence problem - Mailing list pgsql-general

From I. B.
Subject Re: Persistence problem
Date
Msg-id SNT128-W35A440D4B8281E3C7C800191FD0@phx.gbl
Whole thread Raw
In response to Re: Persistence problem  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-general
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.bre@live.com
> CC: kleptog@svana.org; dalroi@solfertje.student.utwente.nl; pgsql-general@postgresql.org
> Subject: Re: [GENERAL] Persistence problem
> Date: Thu, 13 May 2010 15:08:58 -0400
> From: tgl@sss.pgh.pa.us
>
> "I. B." <i.bre@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.

pgsql-general by date:

Previous
From: x y
Date:
Subject: appending items to record variable
Next
From: "Jonathan Tripathy"
Date:
Subject: Re: Authentication method for web app