[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