UPDATE: 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've also found one place in create_mPoint where I used realloc. But why would it matter if I copied the memory into a new variable? Ivan From: i.bre@xxxxxxxx To: kleptog@xxxxxxxxx CC: dalroi@xxxxxxxxxxxxxxxxxxxxxxxxxxxx; pgsql-general@xxxxxxxxxxxxxx Subject: RE: Persistence problem Date: Thu, 13 May 2010 12:04:56 +0200 I'll try to explain with as less code as possible. One of the types I wanted to create is called mpoint. This is a part of code: Datum mpoint_in(PG_FUNCTION_ARGS) { char *str = PG_GETARG_CSTRING(0); mPoint *result; result = (mPoint *) create_mPoint(str); if (result == NULL) { Log ("mpoint_in: reporting error for invalid input syntax for mPoint"); ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for mPoint: \"%s\"", str))); } PG_RETURN_POINTER(result); } In SQL the internallength for the type is set to VARIABLE. The type mpoint is complex. It is a structure containing other structures. typedef struct { int4 length; int noOfUnits; void *units; // this is later casted to uPoint * } mapping_t; typedef mapping_t mPoint; typedef struct { timeint_t interval; double x1, x0, y1, y0; } uPoint; typedef upoint_t uPoint; typedef struct { time_T start, end; short int LC, RC; } timeint_t; typedef struct { double time; short int infinity; } time_T; The function create_mPoint (char *str) creates the type. It is pretty complex and I don't think it's smart to post it here. Anyway, it creates dinamycally array of uPoints for units. During that period, I've used palloc. At the end I set the variable length: result->length = sizeof(int4) + sizeof(int) + result->noOfUnits * sizeof(uPoint); My first guess was that I don't have all the data directly next to each other in the memory. Then I've tried to add this in the function mpoint_in, after I get the result from create_mPoint: mPoint *finalResult; finalResult = (mPoint *)palloc(sizeof(mPoint)); finalResult->units = (uPoint *)palloc(result->noOfUnits * sizeof(uPoint)); memcpy(finalResult->units, result->units, result->noOfUnits * sizeof(uPoint)); finalResult->noOfUnits = result->noOfUnits; finalResult->length = result->length; PG_RETURN_POINTER(finalResult); When I call ToString (I've made it myself), I get the same content for both result and finalResult. However, unlike the first case when I return result and get normal data in that session which dissapears in next one, this time I get corrupted data even in the first session. More code? More explanation? Or someone has an idea? Thank you very much. Ivan > Date: Wed, 12 May 2010 19:45:26 +0200 > From: kleptog@xxxxxxxxx > To: i.bre@xxxxxxxx > CC: dalroi@xxxxxxxxxxxxxxxxxxxxxxxxxxxx; pgsql-general@xxxxxxxxxxxxxx > Subject: Re: Persistence problem > > On Wed, May 12, 2010 at 07:12:10PM +0200, I. B. wrote: > > > > That was my first guess. I used palloc everywhere.. But to be sure, after I made the type, I tried to do the something like: > > > > mytype * result; > > mytype * realResult; > > result = createType(...); > > realResult = (mytype *)palloc(mytype->length); > > mempcy (realResult, result, result->length); > > Did you define the type properly at SQL level? Is it a varlena type or > fixed length? Did you return it properly (as Datum)? > > You're going to need to post more information before we can help you > usefully. > > Have a nice day, > -- > Martijn van Oosterhout <kleptog@xxxxxxxxx> http://svana.org/kleptog/ > > Patriotism is when love of your own people comes first; nationalism, > > when hate for people other than your own comes first. > > - Charles de Gaulle Hotmail: Trusted email with powerful SPAM protection. Sign up now. Hotmail: Trusted email with powerful SPAM protection. Sign up now. |