Re: Persistence problem

From: "I(dot) B(dot)" <i(dot)bre(at)live(dot)com>
To: <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: <kleptog(at)svana(dot)org>, <dalroi(at)solfertje(dot)student(dot)utwente(dot)nl>, <pgsql-general(at)postgresql(dot)org>
Subject: Re: Persistence problem
Date: 2010-05-14 12:35:34
Message-ID: SNT128-W35A440D4B8281E3C7C800191FD0@phx.gbl
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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(dot)bre(at)live(dot)com
> CC: kleptog(at)svana(dot)org; dalroi(at)solfertje(dot)student(dot)utwente(dot)nl; pgsql-general(at)postgresql(dot)org
> Subject: Re: [GENERAL] Persistence problem
> Date: Thu, 13 May 2010 15:08:58 -0400
> From: tgl(at)sss(dot)pgh(dot)pa(dot)us
>
> "I. B." <i(dot)bre(at)live(dot)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.
https://signup.live.com/signup.aspx?id=60969

In response to

Browse pgsql-general by date

  From Date Subject
Next Message x y 2010-05-14 13:12:59 appending items to record variable
Previous Message Scott Mead 2010-05-14 10:47:18 Re: autovacuum: 50% iowait for hours