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 18:03:44
Message-ID: SNT128-W23BFA258D242D02F95202791FD0@phx.gbl
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general


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(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: [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(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. Sign up now.
_________________________________________________________________
Hotmail: Trusted email with powerful SPAM protection.
https://signup.live.com/signup.aspx?id=60969

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Vick Khera 2010-05-14 18:07:25 Re: Pulling data from a constraint def
Previous Message Igor Neyman 2010-05-14 17:49:17 Re: PANIC: corrupted item pointer: 32766