[postgis-devel] Re: [postgis-users] how to identify the_geom that cause : RelateOperation called withLWGEOMCOLLECTION type

Kevin Neufeld kneufeld at refractions.net
Tue Dec 9 11:50:52 PST 2008


Thanx Mark,

Here's an updated patch.  I didn't put the truncation logic in a separate function yet since I'm not sure about freeing 
the memory of a returned char* (looking through the code, sometimes pfree is called, and other times it's not).

Cheers,
Kevin

Mark Cave-Ayland wrote:
> Kevin Neufeld wrote:
> 
>> Mark,
>>
>> Is it fairly trivial to change the elog in lwgeom_geos.c to your fancy 
>> errhint so that when the error is thrown the user has an idea where 
>> the problem occurs?
> 
> Yeah sure. In fact, elog() has been deprecated for a very long time and 
> so in theory we should be using ereport() everywhere.
> 
>> The attached patch seems to work, but I got lost when trying to limit 
>> the output of the LWGEOMCOLLECTION to the first say 128 characters of 
>> the WKT representation.
> 
> Yup, code looks good. The only comment is that you want 
> PARSER_CHECK_NONE instead of PARSER_CHECK_ALL, otherwise the conversion 
> will fail on a non-OGC compliant geometry. So in other words, you only 
> really want PARSER_CHECK_ALL on the input/output functions.
> 
> In terms of truncating the output, you need to do this manually - see 
> http://svn.refractions.net/postgis/trunk/lwgeom/lwgeom_pg.c:pg_parser_errhint 
> for the code I used, although if it is needed in multiple places it may 
> be a good idea to make this a separate function available in liblwgeom.
> 
> 
> HTH,
> 
> Mark.
> 
-------------- next part --------------
Index: lwgeom_geos.c
===================================================================
--- lwgeom_geos.c	(revision 3371)
+++ lwgeom_geos.c	(working copy)
@@ -1020,14 +1020,55 @@
 /*---------------------------------------------*/
 
 
-
+/* 
+ * Throws an ereport ERROR if either geometry is a COLLECTIONTYPE.  Additionally
+ * displays a HINT of the first 80 characters of the WKT representation of the
+ * problematic geometry so a user knows which parameter and which geometry
+ * is causing the problem.
+ */
 void errorIfGeometryCollection(PG_LWGEOM *g1, PG_LWGEOM *g2)
 {
 	int t1 = lwgeom_getType(g1->type);
 	int t2 = lwgeom_getType(g2->type);
+	
+	// Define the hint string include the first 80 characters of the problematic geometry.
+	char hintbuffer[80];
+	
+	LWGEOM_UNPARSER_RESULT lwg_unparser_result;
+	int result;
+	
+	hintbuffer[0] = '\0';
 
-	if (  (t1 == COLLECTIONTYPE) || (t2 == COLLECTIONTYPE) )
-		elog(ERROR,"Relate Operation called with a LWGEOMCOLLECTION type.  This is unsupported");
+	if ( t1 == COLLECTIONTYPE) {
+		result = serialized_lwgeom_to_ewkt(&lwg_unparser_result, SERIALIZED_FORM(g1), PARSER_CHECK_NONE);
+		if (strlen(lwg_unparser_result.wkoutput) < 80) {
+			strcpy(hintbuffer, lwg_unparser_result.wkoutput);
+		}
+		else {
+			strncat(hintbuffer, lwg_unparser_result.wkoutput, 76);
+			strcat(hintbuffer, "...");
+		}
+			
+		ereport(ERROR,
+			(errmsg("Relate Operation called with a LWGEOMCOLLECTION type.  This is unsupported."),
+			 errhint("Change argument 1: '%s'", hintbuffer))
+		);	
+	}
+	else if (t2 == COLLECTIONTYPE) {
+		result = serialized_lwgeom_to_ewkt(&lwg_unparser_result, SERIALIZED_FORM(g2), PARSER_CHECK_NONE);
+		if (strlen(lwg_unparser_result.wkoutput) < 80) {
+			strcpy(hintbuffer, lwg_unparser_result.wkoutput);
+		}
+		else {
+			strncat(hintbuffer, lwg_unparser_result.wkoutput, 76);
+			strcat(hintbuffer, "...");
+		}
+		
+		ereport(ERROR,
+			(errmsg("Relate Operation called with a LWGEOMCOLLECTION type.  This is unsupported."),
+			 errhint("Change argument 2: '%s'", hintbuffer))
+		);	
+	}
 }
 
 PG_FUNCTION_INFO_V1(isvalid);