Debugging my rounding function

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Debugging my rounding function

Gino Lucrezi-2
Unfortunately, PostgreSQL crashes as soon as I call my function, before even
entering it.

I try this command from psql:
select GeomRound( GeomFromText('POINT(358808.488023649
4701948.63964543)',23033), 0::int2 );

Here is what the logfile says:

Jun 30 12:41:41 localhost postgres[9329]: [54] LOG:  Entered geom_round
Jun 30 12:41:41 localhost postgres[6098]: [52] LOG:  server process (pid 9329)
was terminated by signal 11
Jun 30 12:41:41 localhost postgres[6098]: [53] LOG:  terminating any other
active server processes
Jun 30 12:41:41 localhost postgres[6098]: [54] LOG:  all server processes
terminated; reinitializing shared memory and semaphores
Jun 30 12:41:41 localhost postgres[9330]: [55] LOG:  database system was
interrupted at 2004-06-30 12:40:07 CEST

followed by all information about restarting the database

Here are the modifications I did to the source files:
diff ./postgis_fn.c ../postgis-cvs-originale/postgis_fn.c
986,1079d985
< //round geometry
< PG_FUNCTION_INFO_V1(GeomRound);
< Datum geom_round(PG_FUNCTION_ARGS)
< {
<       elog ( LOG, "Entered geom_round" );
<       GEOMETRY                      *geom = (GEOMETRY *)
PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
<       elog ( LOG, "Fetched parameter 0" );
<       GEOMETRY                        *geom1;
<       elog ( LOG, "I'm about to call PG_GETARG_INT16" );
<       int2                    ndigits =  PG_GETARG_INT16(1);
<       int32                           *offsets1;
<       char                            *o1;
<       int32                           type,j,i;
<       POLYGON3D                       *poly;
<       POINT3D                 *point,*pts;
<       LINE3D                  *line;
<       int                             numb_points;
<
<       //make a copy of geom so we can return a new version
<       elog ( LOG, "All geom_round variables have been created and parameters
fetched" );
<
<       geom1 = (GEOMETRY *) palloc (geom->size);
<       memcpy(geom1, geom, geom->size);                        //Will handle
SRID and grid
<
<
<       offsets1 = (int32 *) ( ((char *) &(geom1->objType[0] ))+ sizeof(int32)
* geom1->nobjs ) ;
<
<       //now have to do a scan of each object
<
<       for (j=0; j< geom1->nobjs; j++)         //for each object in geom1
<       {
<               o1 = (char *) geom1 +offsets1[j] ;
<               type=  geom1->objType[j];
<
<               if (type == POINTTYPE)  //point
<               {
<                       point = (POINT3D *) o1;
<                       round_points(point, 1,ndigits);
<               }
<
<               if (type == LINETYPE)   //line
<               {
<                       line = (LINE3D *) o1;
<                       round_points(&(line->points[0]), line->npoints,ndigits);
<               }
<
<               if (type == POLYGONTYPE)        //POLYGON
<               {
<                       poly = (POLYGON3D *) o1;
<                       //find where the points are and where to put them
<                       numb_points =0;
<                       for (i=0; i<poly->nrings;i++)
<                       {
<                               numb_points += poly->npoints[i];
<                       }
<                       pts = (POINT3D *) ( (char *)&(poly->npoints[poly-
>nrings] )  );
<                       pts = (POINT3D *) MAXALIGN(pts);
<                       round_points(pts, numb_points,ndigits);
<               }
<       }
<       //round the bounding box as well
<       geom1->bvol.LLB.x = round( geom1->bvol.LLB.x );
<       geom1->bvol.LLB.y = round( geom1->bvol.LLB.y );
<       geom1->bvol.LLB.z = round( geom1->bvol.LLB.z );
<       geom1->bvol.URT.x = round( geom1->bvol.URT.x );
<       geom1->bvol.URT.y = round( geom1->bvol.URT.y );
<       geom1->bvol.URT.z = round( geom1->bvol.URT.z );
<
<       PG_RETURN_POINTER(geom1);
< }
<
< // Round to ndigits decimal places
< // Contributed by Gino Lucrezi
< void    round_points(POINT3D *pt, int npoints, int2 ndigits)
< {
<         int i;
<
< //printf("rounding %i poinTs by %i digits\n",npoints,ndigits);
<         if (npoints <1)
<                 return; //nothing to do
<
<         for (i=0;i<npoints;i++)
<         {
< //printf("before: [%g,%g,%g]\n", pt[i].x, pt[i].y,pt[i].z);
<
<                 pt[i].x = round( pt[i].x );
<                 pt[i].y = round( pt[i].y );
<                 pt[i].z = round( pt[i].z );
<
< //printf("after: [%g,%g,%g]\n", pt[i].x, pt[i].y,pt[i].z);
<         }
< }
<
< //void    trunc_points(POINT3D *pt, int npoints, int ndigits)


diff ./postgis.h ../postgis-cvs-originale/postgis.h
418,419d417
< void  round_points(POINT3D *pt, int npoints, int2 ndigits);
< //void        trunc_points(POINT3D *pt, int npoints, int2 ndigits);
543,544d540
< Datum geom_round(PG_FUNCTION_ARGS);
< //Datum geom_trunc(PG_FUNCTION_ARGS);


Postgres sees my function thanks to this command:
CREATE OR REPLACE FUNCTION geomround(geometry, int2)
  RETURNS geometry AS
'/usr/local/src/postgresql-7.3.2/contrib/postgis-cvs/libpostgis.so.0.8',
'geom_round'
  LANGUAGE 'c' VOLATILE STRICT;


You might have noticed that I don't yet use the ndigits parameter, but that's
irrelevant.

Anyway, the error happens in
GEOMETRY *geom = (GEOMETRY *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
which I copied shamelessy from the translate() function, so it should be right.
If I remove the call to PG_DETOAST_DATUM it seems to move a bit further, but I don't know if it's needed.

What might I have done wrong?

Thank you!

Gino Lucrezi


Reply | Threaded
Open this post in threaded view
|

Re: Debugging my rounding function

David Blasby-3
Gino Lucrezi wrote:
> Unfortunately, PostgreSQL crashes as soon as I call my function, before even
> entering it.

> < PG_FUNCTION_INFO_V1(GeomRound);
> < Datum geom_round(PG_FUNCTION_ARGS)


You have "GeomRound" in the top line, but "geom_round" in the 2nd line;
they need to be the same.

You're getting a crash because the "PG_FUNCTION_INFO_V1" macro isnt
properly setting up the function so Postgresql can call it (and give it
arguments).
When you get to the line:

"GEOMETRY *geom = (GEOMETRY *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));"

it crashes because its trying to access arguments that havent actually
been sent to the function.

dave