[postgis-devel] Debugging my rounding function

Gino Lucrezi gino-postgisdevel at lucrezi.net
Wed Jun 30 05:53:53 PDT 2004


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




More information about the postgis-devel mailing list