]> granicus.if.org Git - postgis/commitdiff
Nearly finish work on the new parser API. The key part of this patch is to alter...
authorMark Cave-Ayland <mark.cave-ayland@siriusit.co.uk>
Tue, 14 Oct 2008 19:51:24 +0000 (19:51 +0000)
committerMark Cave-Ayland <mark.cave-ayland@siriusit.co.uk>
Tue, 14 Oct 2008 19:51:24 +0000 (19:51 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@3106 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/liblwgeom.h
liblwgeom/lwgparse.c
liblwgeom/lwgunparse.c
liblwgeom/wktparse.h
lwgeom/lwgeom_functions_basic.c
lwgeom/lwgeom_inout.c
lwgeom/lwgeom_ogc.c
lwgeom/lwgeom_pg.c
lwgeom/lwgeom_pg.h
regress/regress_ogc_expected

index 09f0d3e4138eeed717af85cba4a897a0d7b63b6e..e7be95bf95cd3005b7d43026a13559a2871c3fce 100644 (file)
@@ -1123,8 +1123,21 @@ typedef struct struct_lwgeom_parser_result
 {
        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 
  */
@@ -1132,8 +1145,18 @@ 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);
index de5873fb455b6c7e5a38b6051baf9cc458424e6d..beda587fdecbb66b2dd1427682c5044ee90a88b0 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "liblwgeom.h"
 #include "wktparse.h"
+#include "wktparse.tab.h"
 
 /*
  * To get byte order
@@ -43,7 +44,7 @@ typedef void (*read_col_func)(const char **f);
 
 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 @@ tuple* free_list=0;
  */
 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 *first_point=NULL;
 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 @@ alloc_tuple(output_func of,size_t size)
        return ret;
 }
 
-static void
-error(const char* err)
-{
-       error_func(err);
-       ferror_occured=1;
-}
-
 void
 free_tuple(tuple* to_free)
 {
@@ -283,14 +320,14 @@ popc(void)
        /* 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 @@ popc(void)
                        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 @@ check_dims(int num)
 
        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 @@ alloc_polygon(void)
        else
                alloc_stack_tuple(POLYGONTYPE, write_type,1);
 
-       minpoints=3;
+       minpoints=4;
        checkclosed=1;
         isodd=-1;
 
@@ -639,7 +676,7 @@ alloc_curvepolygon(void)
         LWDEBUG(2, "alloc_curvepolygon called.");
 
         alloc_stack_tuple(CURVEPOLYTYPE, write_type, 1);
-        minpoints=3;
+        minpoints=4;
         checkclosed=1;
         isodd=-1;
 }
@@ -774,8 +811,7 @@ lwg_parse_yynotice(char* s)
 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 @@ uchar
 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_wkb_polygon(const char **b)
 
        /* 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 @@ read_wkb_ordinate_array(const char **b)
        alloc_counter();
 
        while(cnt--){
-               if ( ferror_occured )   return;
+               if ( parser_ferror_occured )    return;
                read_wkb_point(b);
        }
 
@@ -981,7 +1023,7 @@ read_collection(const char **b, read_col_func f)
        alloc_counter();
 
        while(cnt--){
-               if ( ferror_occured )   return;
+               if ( parser_ferror_occured )    return;
                f(b);
        }
 
@@ -1007,7 +1049,7 @@ parse_wkb(const char **b)
        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 @@ parse_wkb(const char **b)
                        break;
 
                default:
-                       error("Invalid type in wbk");
+                       LWGEOM_WKB_PARSER_ERROR(PARSER_ERROR_INVALIDWKBTYPE);
        }
 
        the_geom.from_lwgi=0;
@@ -1130,9 +1172,10 @@ parse_it(LWGEOM_PARSER_RESULT *lwg_parser_result, const char *geometry, int flag
        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 @@ parse_it(LWGEOM_PARSER_RESULT *lwg_parser_result, const char *geometry, int flag
 
        close_parser();
 
-       if (ferror_occured)
-               return 0;
-
        /* Return the parsed geometry */
        make_serialized_lwgeom(lwg_parser_result);
 
-       return -1;
+       return parser_ferror_occured;
 }
 
 int
index e6893a2bd739dc60c1d626dff5c4a4a2705a3754..ae44f4e38f5ecc90842b45622f33fd342febaa68 100644 (file)
@@ -64,6 +64,7 @@ uchar* output_wkb(uchar* geom);
 
 /*-- Globals ----------------------------------------------- */
 
+static int unparser_ferror_occured;
 static int dims;
 static allocator local_malloc;
 static freeor local_free;
@@ -81,9 +82,43 @@ void (*write_wkb_bytes)(uchar* ptr,unsigned int cnt,size_t size);
 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,10 +276,7 @@ uchar *
 output_line_collection(uchar* geom,outfunc func,int supress)
 {
        int cnt = read_int(&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");
+       int orig_cnt = cnt;
 
        if ( cnt == 0 ){
                write_str(" EMPTY");
@@ -259,6 +291,11 @@ output_line_collection(uchar* geom,outfunc func,int supress)
                }
                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 @@ output_polygon_ring_collection(uchar* geom,outfunc func,int supress)
         double last_point[dims];
 
        int cnt = read_int(&geom);
+       int orig_cnt = cnt;
        if ( cnt == 0 ){
                write_str(" EMPTY");
        }
@@ -309,8 +347,11 @@ output_polygon_ring_collection(uchar* geom,outfunc func,int supress)
                /* 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,14 +361,7 @@ uchar *
 output_curve_collection(uchar* geom,outfunc func,int supress)
 {
        int cnt = read_int(&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");
-
-       /* 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");
+       int orig_cnt = cnt;
 
        if ( cnt == 0 ){
                write_str(" EMPTY");
@@ -342,6 +376,17 @@ output_curve_collection(uchar* geom,outfunc func,int supress)
                }
                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 @@ unparse_WKT(LWGEOM_UNPARSER_RESULT *lwg_unparser_result, uchar* serialized, allo
                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 @@ unparse_WKT(LWGEOM_UNPARSER_RESULT *lwg_unparser_result, uchar* serialized, allo
        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 @@ uchar *
 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);
 
-       /* Ensure that LINESTRING has a minimum of 2 points */
-        if ((current_unparser_check_flags & PARSER_CHECK_MINPOINTS) && cnt < 2)
-                lwerror("geometry requires more points");
-
        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) && orig_cnt < 2) {
+               LWGEOM_WKB_UNPARSER_ERROR(UNPARSER_ERROR_MOREPOINTS);
+       }
+
        return geom;
 }
 
@@ -729,6 +778,7 @@ output_wkb_polygon_ring_collection(uchar* geom,outwkbfunc func)
        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,8 +808,13 @@ output_wkb_polygon_ring_collection(uchar* geom,outwkbfunc func)
 
        /* 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 @@ uchar *
 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 @@ unparse_WKB(LWGEOM_UNPARSER_RESULT *lwg_unparser_result, uchar* serialized, allo
                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 @@ unparse_WKB(LWGEOM_UNPARSER_RESULT *lwg_unparser_result, uchar* serialized, allo
        lwg_unparser_result->wkoutput = out_start;
        lwg_unparser_result->size = (out_pos-out_start);
 
-       return -1;      
+       return unparser_ferror_occured; 
 }
 
 
index e02775cdf39745faea59b9919b3441e6267375da..8a2ec08fb0704baaa1291924f92b2f673e987bfd 100644 (file)
@@ -23,12 +23,17 @@ typedef struct serialized_lwgeom {
 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);
index 07ee4c370288fedc0dabaa193ebe666c0b856fc9..cae6f4fc399247bcca3e670a6f017476c8690fb6 100644 (file)
@@ -2949,6 +2949,8 @@ Datum LWGEOM_asEWKT(PG_FUNCTION_ARGS)
        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,';');
index 1d3fc858ce914d8282b91a14f6ba871f0787ad85..755c858697ad4c9f66ba1eb8570b8e65dcc0a3c5 100644 (file)
@@ -70,6 +70,8 @@ Datum LWGEOM_in(PG_FUNCTION_ARGS)
 
        /* 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 @@ Datum LWGEOM_out(PG_FUNCTION_ARGS)
 
        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 @@ Datum LWGEOM_asHEXEWKB(PG_FUNCTION_ARGS)
        }
 
        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 @@ Datum LWGEOM_to_text(PG_FUNCTION_ARGS)
 
        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 @@ Datum WKBFromLWGEOM(PG_FUNCTION_ARGS)
 
 #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 @@ Datum WKBFromLWGEOM(PG_FUNCTION_ARGS)
 #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 @@ Datum parse_WKT_lwgeom(PG_FUNCTION_ARGS)
        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);
     
index 690da12846658f0dab6e2f0f2911f28d0c2089cd..a4acb2787b94cca6607f0390c74d39df0940b3c0 100644 (file)
@@ -1004,6 +1004,8 @@ Datum LWGEOM_from_text(PG_FUNCTION_ARGS)
        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 @@ Datum LWGEOM_asText(PG_FUNCTION_ARGS)
                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,';');
 
index ab6aa8f204fa067bbda7fcc1451c9eaaac98df0f..43af4db84d63d38b52864d16543d7434fd5a3f96 100644 (file)
 PG_MODULE_MAGIC;
 #endif
 
+/*
+ * Global pointer for parser/unparser error messages
+ */
+char *parser_message;
+
+
 void *
 pg_alloc(size_t size)
 {
@@ -258,6 +264,8 @@ pglwgeom_from_ewkb(uchar *ewkb, int flags, size_t ewkblen)
        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 @@ pglwgeom_to_ewkb(PG_LWGEOM *geom, int flags, char byteorder, size_t *outsize)
 {
        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;
 }
 
 /*
index 376c091af6bce7026897d332c13381bb9ba74c4f..7267709cb81b7e478ddee7542db41b4d764760ed 100644 (file)
@@ -45,6 +45,23 @@ void pg_notice(const char *msg, va_list vp);
 #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);
index 62879a022a6e876646bea1f2f2d87d7f3e8851a0..99f890a415fd03e6d3e20edfb9a1b605e9d75704 100644 (file)
@@ -72,8 +72,7 @@ polygonize_garray|GEOMETRYCOLLECTION EMPTY
 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