[postgis-commits] svn - r3106 - in trunk: liblwgeom lwgeom regress
postgis-commits at postgis.refractions.net
postgis-commits at postgis.refractions.net
Tue Oct 14 12:51:24 PDT 2008
Author: mcayland
Date: 2008-10-14 12:51:24 -0700 (Tue, 14 Oct 2008)
New Revision: 3106
Modified:
trunk/liblwgeom/liblwgeom.h
trunk/liblwgeom/lwgparse.c
trunk/liblwgeom/lwgunparse.c
trunk/liblwgeom/wktparse.h
trunk/lwgeom/lwgeom_functions_basic.c
trunk/lwgeom/lwgeom_inout.c
trunk/lwgeom/lwgeom_ogc.c
trunk/lwgeom/lwgeom_pg.c
trunk/lwgeom/lwgeom_pg.h
trunk/regress/regress_ogc_expected
Log:
Nearly finish work on the new parser API. The key part of this patch is to alter the behaviour of the parser so that instead of generating errors directly, it returns an error code, error location and an error message. Hence the caller is now in charge of the behaviour when parsing invalid geometries, and so can ignore errors or proceed onto the next geometry if required. The regression test change is due to a change in an error message, since the error is now returned from the unparser before it even gets to GEOS.
Modified: trunk/liblwgeom/liblwgeom.h
===================================================================
--- trunk/liblwgeom/liblwgeom.h 2008-10-14 19:39:07 UTC (rev 3105)
+++ trunk/liblwgeom/liblwgeom.h 2008-10-14 19:51:24 UTC (rev 3106)
@@ -1123,17 +1123,40 @@
{
uchar *serialized_lwgeom; /* Pointer to serialized LWGEOM */
int size; /* Size of serialized LWGEOM in bytes */
+ const char *message; /* Error/warning message */
+ int errlocation; /* Location of error */
} LWGEOM_PARSER_RESULT;
/*
+ * Parser error messages (these must match the message array in lwgparse.c)
+ */
+#define PARSER_ERROR_MOREPOINTS 1
+#define PARSER_ERROR_ODDPOINTS 2
+#define PARSER_ERROR_UNCLOSED 3
+#define PARSER_ERROR_MIXDIMS 4
+#define PARSER_ERROR_INVALIDGEOM 5
+#define PARSER_ERROR_INVALIDWKBTYPE 6
+
+
+/*
* Unparser result structure: returns the result of attempting to convert LWGEOM to (E)WKT/(E)WKB
*/
typedef struct struct_lwgeom_unparser_result
{
char *wkoutput; /* Pointer to WKT or WKB output */
int size; /* Size of serialized LWGEOM in bytes */
+ const char *message; /* Error/warning message */
+ int errlocation; /* Location of error */
} LWGEOM_UNPARSER_RESULT;
+/*
+ * Unparser error messages (these must match the message array in lwgunparse.c)
+ */
+#define UNPARSER_ERROR_MOREPOINTS 1
+#define UNPARSER_ERROR_ODDPOINTS 2
+#define UNPARSER_ERROR_UNCLOSED 3
+
+
/* Parser access routines */
extern char *lwgeom_to_ewkt(LWGEOM *lwgeom, int flags);
extern char *lwgeom_to_hexwkb(LWGEOM *lwgeom, int flags, unsigned int byteorder);
Modified: trunk/liblwgeom/lwgparse.c
===================================================================
--- trunk/liblwgeom/lwgparse.c 2008-10-14 19:39:07 UTC (rev 3105)
+++ trunk/liblwgeom/lwgparse.c 2008-10-14 19:51:24 UTC (rev 3106)
@@ -13,6 +13,7 @@
#include "liblwgeom.h"
#include "wktparse.h"
+#include "wktparse.tab.h"
/*
* To get byte order
@@ -43,7 +44,7 @@
int srid=-1;
-static int ferror_occured;
+static int parser_ferror_occured;
static allocator local_malloc;
static report_error error_func;
@@ -99,13 +100,18 @@
*/
int current_parser_check_flags;
+/*
+ * Parser current instance result structure - the result structure being used for the current parse
+ */
+LWGEOM_PARSER_RESULT *current_lwg_parser_result;
+
/* Parser state flags - these are set automatically by the parser */
int minpoints;
int checkclosed;
/*
- * This inicates if the number of points in the geometry is required to
+ * This indicates if the number of points in the geometry is required to
* be odd (one) or even (zero, currently not enforced) or whatever (-one)
*/
int isodd;
@@ -113,12 +119,50 @@
double *last_point=NULL;
+/*
+ * Parser error messages
+ *
+ * IMPORTANT: Make sure the order of these messages matches the PARSER_ERROR constants in liblwgeom.h!
+ * The 0th element should always be empty since it is unused (error constants start from -1)
+ */
+
+const char *parser_error_messages[] = {
+ "",
+ "geometry requires more points",
+ "geometry must have an odd number of points",
+ "geometry contains non-closed rings",
+ "can not mix dimensionality in a geometry",
+ "parse error - invalid geometry",
+ "invalid WKB type"
+};
+
+/* Macro to return the error message and the current position within WKT */
+#define LWGEOM_WKT_PARSER_ERROR(errcode) \
+ do { \
+ if (!parser_ferror_occured) { \
+ parser_ferror_occured = -1 * errcode; \
+ current_lwg_parser_result->message = parser_error_messages[errcode]; \
+ current_lwg_parser_result->errlocation = lwg_parse_yylloc.last_column; \
+ } \
+ } while (0);
+
+
+/* Macro to return the error message and the current position within WKB
+ NOTE: the position is handled automatically by strhex_readbyte */
+#define LWGEOM_WKB_PARSER_ERROR(errcode) \
+ do { \
+ if (!parser_ferror_occured) { \
+ parser_ferror_occured = -1 * errcode; \
+ current_lwg_parser_result->message = parser_error_messages[errcode]; \
+ } \
+ } while (0);
+
+
/* External functions */
extern void init_parser(const char *);
/* Prototypes */
tuple* alloc_tuple(output_func of,size_t size);
-static void error(const char* err);
void free_tuple(tuple* to_free);
void inc_num(void);
void alloc_stack_tuple(int type,output_func of,size_t size);
@@ -222,13 +266,6 @@
return ret;
}
-static void
-error(const char* err)
-{
- error_func(err);
- ferror_occured=1;
-}
-
void
free_tuple(tuple* to_free)
{
@@ -283,14 +320,14 @@
/* If the minimum point check has been enabled, perform it */
if (current_parser_check_flags & PARSER_CHECK_MINPOINTS) {
if ( the_geom.stack->uu.nn.num < minpoints){
- error("geometry requires more points");
+ LWGEOM_WKT_PARSER_ERROR(PARSER_ERROR_MOREPOINTS);
}
}
/* If the odd number point check has been enabled, perform it */
if (current_parser_check_flags & PARSER_CHECK_ODD) {
if(isodd != -1 && the_geom.stack->uu.nn.num % 2 != isodd) {
- error("geometry must have an odd number of points");
+ LWGEOM_WKT_PARSER_ERROR(PARSER_ERROR_ODDPOINTS);
}
}
@@ -300,7 +337,7 @@
if ( memcmp(first_point, last_point,
sizeof(double)*the_geom.ndims) )
{
- error("geometry contains non-closed rings");
+ LWGEOM_WKT_PARSER_ERROR(PARSER_ERROR_UNCLOSED);
}
}
}
@@ -316,7 +353,7 @@
if( the_geom.ndims != num){
if (the_geom.ndims) {
- error("Can not mix dimensionality in a geometry");
+ LWGEOM_WKT_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
} else {
LWDEBUGF(3, "check_dims: setting dim %d", num);
@@ -627,7 +664,7 @@
else
alloc_stack_tuple(POLYGONTYPE, write_type,1);
- minpoints=3;
+ minpoints=4;
checkclosed=1;
isodd=-1;
@@ -639,7 +676,7 @@
LWDEBUG(2, "alloc_curvepolygon called.");
alloc_stack_tuple(CURVEPOLYTYPE, write_type, 1);
- minpoints=3;
+ minpoints=4;
checkclosed=1;
isodd=-1;
}
@@ -774,8 +811,7 @@
int
lwg_parse_yyerror(char* s)
{
- error("parse error - invalid geometry");
- /* error_func("parse error - invalid geometry"); */
+ LWGEOM_WKT_PARSER_ERROR(PARSER_ERROR_INVALIDGEOM);
return 1;
}
@@ -809,12 +845,18 @@
strhex_readbyte(const char* in)
{
if ( *in == 0 ){
- if ( ! ferror_occured){
- error("invalid wkb");
+ if ( ! parser_ferror_occured){
+ LWGEOM_WKB_PARSER_ERROR(PARSER_ERROR_INVALIDGEOM);
}
return 0;
}
- return to_hex[(int)*in]<<4 | to_hex[(int)*(in+1)];
+
+ if (!parser_ferror_occured) {
+ lwg_parse_yylloc.last_column++;
+ return to_hex[(int)*in]<<4 | to_hex[(int)*(in+1)];
+ } else {
+ return 0;
+ }
}
uchar
@@ -919,10 +961,10 @@
/* Read through each ORDINATE_ARRAY in turn */
while(cnt--){
- if ( ferror_occured ) return;
+ if ( parser_ferror_occured ) return;
/* Things to check for POLYGON ORDINATE_ARRAYs */
- minpoints=3;
+ minpoints=4;
checkclosed=1;
isodd=-1;
@@ -965,7 +1007,7 @@
alloc_counter();
while(cnt--){
- if ( ferror_occured ) return;
+ if ( parser_ferror_occured ) return;
read_wkb_point(b);
}
@@ -981,7 +1023,7 @@
alloc_counter();
while(cnt--){
- if ( ferror_occured ) return;
+ if ( parser_ferror_occured ) return;
f(b);
}
@@ -1007,7 +1049,7 @@
type = read_wkb_int(b);
/* quick exit on error */
- if ( ferror_occured ) return;
+ if ( parser_ferror_occured ) return;
the_geom.ndims=2;
if (type & WKBZOFFSET)
@@ -1102,7 +1144,7 @@
break;
default:
- error("Invalid type in wbk");
+ LWGEOM_WKB_PARSER_ERROR(PARSER_ERROR_INVALIDWKBTYPE);
}
the_geom.from_lwgi=0;
@@ -1130,9 +1172,10 @@
local_malloc = allocfunc;
error_func=errfunc;
- ferror_occured = 0;
+ parser_ferror_occured = 0;
/* Setup the inital parser flags and empty the return struct */
+ current_lwg_parser_result = lwg_parser_result;
current_parser_check_flags = flags;
lwg_parser_result->serialized_lwgeom = NULL;
lwg_parser_result->size = 0;
@@ -1143,13 +1186,10 @@
close_parser();
- if (ferror_occured)
- return 0;
-
/* Return the parsed geometry */
make_serialized_lwgeom(lwg_parser_result);
- return -1;
+ return parser_ferror_occured;
}
int
Modified: trunk/liblwgeom/lwgunparse.c
===================================================================
--- trunk/liblwgeom/lwgunparse.c 2008-10-14 19:39:07 UTC (rev 3105)
+++ trunk/liblwgeom/lwgunparse.c 2008-10-14 19:51:24 UTC (rev 3106)
@@ -64,6 +64,7 @@
/*-- Globals ----------------------------------------------- */
+static int unparser_ferror_occured;
static int dims;
static allocator local_malloc;
static freeor local_free;
@@ -81,10 +82,44 @@
int current_unparser_check_flags;
/*
- * Unparser result structure
+ * Unparser current instance result structure - the result structure being used for the current unparse
*/
-LWGEOM_UNPARSER_RESULT *unparser_result;
+LWGEOM_UNPARSER_RESULT *current_lwg_unparser_result;
+/*
+ * Unparser error messages
+ *
+ * IMPORTANT: Make sure the order of these messages matches the UNPARSER_ERROR constants in liblwgeom.h!
+ * The 0th element should always be empty since it is unused (error constants start from -1)
+ */
+
+const char *unparser_error_messages[] = {
+ "",
+ "geometry requires more points",
+ "geometry must have an odd number of points",
+ "geometry contains non-closed rings"
+};
+
+/* Macro to return the error message and the current position within WKT */
+#define LWGEOM_WKT_UNPARSER_ERROR(errcode) \
+ do { \
+ if (!unparser_ferror_occured) { \
+ unparser_ferror_occured = -1 * errcode; \
+ current_lwg_unparser_result->message = unparser_error_messages[errcode]; \
+ current_lwg_unparser_result->errlocation = (out_pos - out_start); \
+ } \
+ } while (0);
+
+/* Macro to return the error message and the current position within WKB */
+#define LWGEOM_WKB_UNPARSER_ERROR(errcode) \
+ do { \
+ if (!unparser_ferror_occured) { \
+ unparser_ferror_occured = -1 * errcode; \
+ current_lwg_unparser_result->message = unparser_error_messages[errcode]; \
+ current_lwg_unparser_result->errlocation = (out_pos - out_start); \
+ } \
+ } while (0);
+
/*---------------------------------------------------------- */
@@ -241,11 +276,8 @@
output_line_collection(uchar* geom,outfunc func,int supress)
{
int cnt = read_int(&geom);
+ int orig_cnt = cnt;
- /* Ensure that LINESTRING has a minimum of 2 points */
- if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && cnt < 2)
- lwerror("geometry requires more points");
-
if ( cnt == 0 ){
write_str(" EMPTY");
}
@@ -259,6 +291,11 @@
}
write_str(")");
}
+
+ /* Ensure that LINESTRING has a minimum of 2 points */
+ if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && orig_cnt < 2)
+ LWGEOM_WKT_UNPARSER_ERROR(UNPARSER_ERROR_MOREPOINTS);
+
return geom;
}
@@ -272,6 +309,7 @@
double last_point[dims];
int cnt = read_int(&geom);
+ int orig_cnt = cnt;
if ( cnt == 0 ){
write_str(" EMPTY");
}
@@ -309,8 +347,11 @@
/* Check if they are the same... */
if (memcmp(&first_point, &last_point, sizeof(double) * dims) &&
(current_unparser_check_flags & PARSER_CHECK_CLOSURE))
- lwerror("geometry contains non-closed rings");
+ LWGEOM_WKT_UNPARSER_ERROR(UNPARSER_ERROR_UNCLOSED);
+ /* Ensure that POLYGON has a minimum of 4 points */
+ if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && orig_cnt < 4)
+ LWGEOM_WKT_UNPARSER_ERROR(UNPARSER_ERROR_MOREPOINTS);
}
return geom;
}
@@ -320,15 +361,8 @@
output_curve_collection(uchar* geom,outfunc func,int supress)
{
int cnt = read_int(&geom);
+ int orig_cnt = cnt;
- /* Ensure that a CIRCULARSTRING has a minimum of 3 points */
- if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && cnt < 3)
- lwerror("geometry requires more points");
-
- /* Ensure that a CIRCULARSTRING has an odd number of points */
- if ((current_unparser_check_flags & PARSER_CHECK_ODD) && cnt % 2 != 1)
- lwerror("geometry must have an odd number of points");
-
if ( cnt == 0 ){
write_str(" EMPTY");
}
@@ -342,6 +376,17 @@
}
write_str(")");
}
+
+ /* Ensure that a CIRCULARSTRING has a minimum of 3 points */
+ if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && orig_cnt < 3) {
+ LWGEOM_WKT_UNPARSER_ERROR(UNPARSER_ERROR_MOREPOINTS);
+ }
+
+ /* Ensure that a CIRCULARSTRING has an odd number of points */
+ if ((current_unparser_check_flags & PARSER_CHECK_ODD) && orig_cnt % 2 != 1) {
+ LWGEOM_WKT_UNPARSER_ERROR(UNPARSER_ERROR_ODDPOINTS);
+ }
+
return geom;
}
@@ -579,11 +624,12 @@
return 0;
/* Setup the inital parser flags and empty the return struct */
+ current_lwg_unparser_result = lwg_unparser_result;
current_unparser_check_flags = flags;
lwg_unparser_result->wkoutput = NULL;
lwg_unparser_result->size = 0;
- unparser_result = lwg_unparser_result;
+ unparser_ferror_occured = 0;
local_malloc=alloc;
local_free=free;
len = 128;
@@ -596,7 +642,7 @@
lwg_unparser_result->wkoutput = out_start;
lwg_unparser_result->size = strlen(out_start);
- return -1;
+ return unparser_ferror_occured;
}
static char outchr[]={"0123456789ABCDEF" };
@@ -707,15 +753,18 @@
output_wkb_line_collection(uchar* geom,outwkbfunc func)
{
int cnt = read_int(&geom);
+ int orig_cnt = cnt;
LWDEBUGF(2, "output_wkb_line_collection: %d iterations loop", cnt);
+ write_wkb_int(cnt);
+ while(cnt--) geom=func(geom);
+
/* Ensure that LINESTRING has a minimum of 2 points */
- if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && cnt < 2)
- lwerror("geometry requires more points");
+ if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && orig_cnt < 2) {
+ LWGEOM_WKB_UNPARSER_ERROR(UNPARSER_ERROR_MOREPOINTS);
+ }
- write_wkb_int(cnt);
- while(cnt--) geom=func(geom);
return geom;
}
@@ -729,6 +778,7 @@
double last_point[dims];
int cnt = read_int(&geom);
+ int orig_cnt = cnt;
LWDEBUGF(2, "output_wkb_polygon_ring_collection: %d iterations loop", cnt);
@@ -758,9 +808,14 @@
/* Check if they are the same... */
if (memcmp(&first_point, &last_point, sizeof(double) * dims) &&
- (current_unparser_check_flags & PARSER_CHECK_CLOSURE))
- lwerror("geometry contains non-closed rings");
+ (current_unparser_check_flags & PARSER_CHECK_CLOSURE)) {
+ LWGEOM_WKB_UNPARSER_ERROR(UNPARSER_ERROR_UNCLOSED);
+ }
+ /* Ensure that POLYGON has a minimum of 4 points */
+ if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && orig_cnt < 4)
+ LWGEOM_WKT_UNPARSER_ERROR(UNPARSER_ERROR_MOREPOINTS);
+
return geom;
}
@@ -778,19 +833,23 @@
output_wkb_curve_collection(uchar* geom,outwkbfunc func)
{
int cnt = read_int(&geom);
+ int orig_cnt = cnt;
LWDEBUGF(2, "output_wkb_curve_collection: %d iterations loop", cnt);
+ write_wkb_int(cnt);
+ while(cnt--) geom=func(geom);
+
/* Ensure that a CIRCULARSTRING has a minimum of 3 points */
- if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && cnt < 3)
- lwerror("geometry requires more points");
+ if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && orig_cnt < 3) {
+ LWGEOM_WKB_UNPARSER_ERROR(UNPARSER_ERROR_MOREPOINTS);
+ }
/* Ensure that a CIRCULARSTRING has an odd number of points */
- if ((current_unparser_check_flags & PARSER_CHECK_ODD) && cnt % 2 != 1)
- lwerror("geometry must have an odd number of points");
+ if ((current_unparser_check_flags & PARSER_CHECK_ODD) && orig_cnt % 2 != 1) {
+ LWGEOM_WKB_UNPARSER_ERROR(UNPARSER_ERROR_ODDPOINTS);
+ }
- write_wkb_int(cnt);
- while(cnt--) geom=func(geom);
return geom;
}
@@ -893,11 +952,12 @@
return 0;
/* Setup the inital parser flags and empty the return struct */
+ current_lwg_unparser_result = lwg_unparser_result;
current_unparser_check_flags = flags;
lwg_unparser_result->wkoutput = NULL;
lwg_unparser_result->size = 0;
- unparser_result = lwg_unparser_result;
+ unparser_ferror_occured = 0;
local_malloc=alloc;
local_free=free;
len = 128;
@@ -936,7 +996,7 @@
lwg_unparser_result->wkoutput = out_start;
lwg_unparser_result->size = (out_pos-out_start);
- return -1;
+ return unparser_ferror_occured;
}
Modified: trunk/liblwgeom/wktparse.h
===================================================================
--- trunk/liblwgeom/wktparse.h 2008-10-14 19:39:07 UTC (rev 3105)
+++ trunk/liblwgeom/wktparse.h 2008-10-14 19:51:24 UTC (rev 3106)
@@ -23,12 +23,17 @@
typedef struct struct_lwgeom_parser_result
{
SERIALIZED_LWGEOM *serialized_lwgeom;
+ int size;
+ const char *message;
+ int errlocation;
} LWGEOM_PARSER_RESULT;
typedef struct struct_lwgeom_unparser_result
{
char *wkoutput;
int size;
+ const char *message;
+ int errlocation;
} LWGEOM_UNPARSER_RESULT;
#endif
typedef void* (*allocator)(size_t size);
Modified: trunk/lwgeom/lwgeom_functions_basic.c
===================================================================
--- trunk/lwgeom/lwgeom_functions_basic.c 2008-10-14 19:39:07 UTC (rev 3105)
+++ trunk/lwgeom/lwgeom_functions_basic.c 2008-10-14 19:51:24 UTC (rev 3106)
@@ -2949,6 +2949,8 @@
lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
result = serialized_lwgeom_to_ewkt(&lwg_unparser_result, SERIALIZED_FORM(lwgeom), PARSER_CHECK_ALL);
+ if (result)
+ PG_UNPARSER_ERROR(lwg_unparser_result);
#if 0
semicolonLoc = strchr(lwg_unparser_result.wkb,';');
Modified: trunk/lwgeom/lwgeom_inout.c
===================================================================
--- trunk/lwgeom/lwgeom_inout.c 2008-10-14 19:39:07 UTC (rev 3105)
+++ trunk/lwgeom/lwgeom_inout.c 2008-10-14 19:51:24 UTC (rev 3106)
@@ -70,6 +70,8 @@
/* will handle both HEXEWKB and EWKT */
result = serialized_lwgeom_from_ewkt(&lwg_parser_result, str, PARSER_CHECK_ALL);
+ if (result)
+ PG_PARSER_ERROR(lwg_parser_result);
lwgeom = lwgeom_deserialize(lwg_parser_result.serialized_lwgeom);
@@ -101,6 +103,8 @@
lwgeom = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
result = serialized_lwgeom_to_hexwkb(&lwg_unparser_result, SERIALIZED_FORM(lwgeom), PARSER_CHECK_ALL, -1);
+ if (result)
+ PG_UNPARSER_ERROR(lwg_unparser_result);
PG_RETURN_CSTRING(lwg_unparser_result.wkoutput);
}
@@ -141,6 +145,8 @@
}
result = serialized_lwgeom_to_hexwkb(&lwg_unparser_result, SERIALIZED_FORM(lwgeom), PARSER_CHECK_ALL, byteorder);
+ if (result)
+ PG_UNPARSER_ERROR(lwg_unparser_result);
text_result = palloc(lwg_unparser_result.size+VARHDRSZ);
memcpy(VARDATA(text_result),lwg_unparser_result.wkoutput,lwg_unparser_result.size);
@@ -168,6 +174,8 @@
lwgeom = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
result = serialized_lwgeom_to_hexwkb(&lwg_unparser_result, SERIALIZED_FORM(lwgeom), PARSER_CHECK_ALL, -1);
+ if (result)
+ PG_UNPARSER_ERROR(lwg_unparser_result);
text_result = palloc(lwg_unparser_result.size+VARHDRSZ);
memcpy(VARDATA(text_result),lwg_unparser_result.wkoutput,lwg_unparser_result.size);
@@ -269,6 +277,8 @@
#ifdef BINARY_FROM_HEX
result = serialized_lwgeom_to_hexwkb(&lwg_unparser_result, SERIALIZED_FORM(lwgeom_input), byteorder);
+ if (result)
+ PG_UNPARSER_ERROR(lwg_unparser_result);
LWDEBUGF(3, "in WKBFromLWGEOM with WKB = '%s'", lwg_unparser_result.wkoutput);
@@ -298,6 +308,8 @@
#else /* ndef BINARY_FROM_HEX */
result = serialized_lwgeom_to_ewkb(&lwg_unparser_result, SERIALIZED_FORM(lwgeom_input), PARSER_CHECK_ALL, byteorder);
+ if (result)
+ PG_UNPARSER_ERROR(lwg_unparser_result);
size_result = lwg_unparser_result.size+VARHDRSZ;
lwgeom_result = palloc(size_result);
@@ -480,6 +492,8 @@
POSTGIS_DEBUGF(3, "in parse_WKT_lwgeom with input: '%s'",wkt);
result = serialized_lwgeom_from_ewkt(&lwg_parser_result, wkt, PARSER_CHECK_ALL);
+ if (result)
+ PG_PARSER_ERROR(lwg_parser_result);
lwgeom = lwgeom_deserialize(lwg_parser_result.serialized_lwgeom);
Modified: trunk/lwgeom/lwgeom_ogc.c
===================================================================
--- trunk/lwgeom/lwgeom_ogc.c 2008-10-14 19:39:07 UTC (rev 3105)
+++ trunk/lwgeom/lwgeom_ogc.c 2008-10-14 19:51:24 UTC (rev 3106)
@@ -1004,6 +1004,8 @@
POSTGIS_DEBUGF(3, "wkt: [%s]", wkt);
result = serialized_lwgeom_from_ewkt(&lwg_parser_result, wkt, PARSER_CHECK_ALL);
+ if (result)
+ PG_PARSER_ERROR(lwg_parser_result);
lwgeom = lwgeom_deserialize(lwg_parser_result.serialized_lwgeom);
@@ -1081,6 +1083,8 @@
LWGEOM_force_2d, PointerGetDatum(lwgeom)));
result = serialized_lwgeom_to_ewkt(&lwg_unparser_result, SERIALIZED_FORM(ogclwgeom), PARSER_CHECK_ALL);
+ if (result)
+ PG_UNPARSER_ERROR(lwg_unparser_result);
semicolonLoc = strchr(lwg_unparser_result.wkoutput,';');
Modified: trunk/lwgeom/lwgeom_pg.c
===================================================================
--- trunk/lwgeom/lwgeom_pg.c 2008-10-14 19:39:07 UTC (rev 3105)
+++ trunk/lwgeom/lwgeom_pg.c 2008-10-14 19:51:24 UTC (rev 3106)
@@ -19,6 +19,12 @@
PG_MODULE_MAGIC;
#endif
+/*
+ * Global pointer for parser/unparser error messages
+ */
+char *parser_message;
+
+
void *
pg_alloc(size_t size)
{
@@ -258,6 +264,8 @@
hexewkb[hexewkblen] = '\0';
result = serialized_lwgeom_from_ewkt(&lwg_parser_result, hexewkb, flags);
+ if (result)
+ PG_PARSER_ERROR(lwg_parser_result);
ret = (PG_LWGEOM *)palloc(lwg_parser_result.size + VARHDRSZ);
SET_VARSIZE(ret, lwg_parser_result.size + VARHDRSZ);
@@ -276,12 +284,20 @@
{
LWGEOM_UNPARSER_RESULT lwg_unparser_result;
int result;
+ char *wkoutput;
uchar *srl = &(geom->type);
result = serialized_lwgeom_to_ewkb(&lwg_unparser_result, srl, flags, byteorder);
+ if (result)
+ PG_UNPARSER_ERROR(lwg_unparser_result);
*outsize = lwg_unparser_result.size;
- return lwg_unparser_result.wkoutput;
+
+ /* Make a copy of the wkoutput so it can be used outside of the function */
+ wkoutput = palloc(lwg_unparser_result.size);
+ memcpy(wkoutput, lwg_unparser_result.wkoutput, lwg_unparser_result.size);
+
+ return wkoutput;
}
/*
Modified: trunk/lwgeom/lwgeom_pg.h
===================================================================
--- trunk/lwgeom/lwgeom_pg.h 2008-10-14 19:39:07 UTC (rev 3105)
+++ trunk/lwgeom/lwgeom_pg.h 2008-10-14 19:51:24 UTC (rev 3106)
@@ -45,6 +45,23 @@
#endif
+/*
+ * Standard macro for reporting parser errors to PostgreSQL
+ */
+#define PG_PARSER_ERROR(lwg_parser_result) \
+ do { \
+ elog(ERROR, "%s", lwg_parser_result.message); \
+ } while(0);
+
+/*
+ * Standard macro for reporting unparser errors to PostgreSQL
+ */
+#define PG_UNPARSER_ERROR(lwg_unparser_result) \
+ do { \
+ elog(ERROR, "%s", lwg_unparser_result.message); \
+ } while(0);
+
+
/* Serialize/deserialize a PG_LWGEOM (postgis datatype) */
extern PG_LWGEOM *pglwgeom_serialize(LWGEOM *lwgeom);
extern LWGEOM *pglwgeom_deserialize(PG_LWGEOM *pglwgeom);
Modified: trunk/regress/regress_ogc_expected
===================================================================
--- trunk/regress/regress_ogc_expected 2008-10-14 19:39:07 UTC (rev 3105)
+++ trunk/regress/regress_ogc_expected 2008-10-14 19:51:24 UTC (rev 3106)
@@ -72,8 +72,7 @@
polygonize_garray|POLYGON((10 0,0 0,0 10,10 10,10 0))
linemerge149|LINESTRING(-5 -5,0 0,1 1,4 4)
intersects|f
-NOTICE: IllegalArgumentException: Number of points must be 0 or >3
-ERROR: POSTGIS2GEOS conversion failed
+ERROR: geometry requires more points
buffer|POLYGON((1 0,0.707107 -0.707107,0 -1,-0.707107 -0.707107,-1 0,-0.707107 0.707107,0 1,0.707107 0.707107,1 0))
geomunion|MULTIPOINT(0 0,1 1)
unite_garray|t
More information about the postgis-commits
mailing list