diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_geofunc.cc | 23 | ||||
-rw-r--r-- | sql/spatial.cc | 47 | ||||
-rw-r--r-- | sql/spatial.h | 22 |
3 files changed, 60 insertions, 32 deletions
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 560d822bea7..8c9b61d98a1 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -131,13 +131,27 @@ String *Item_func_geometry_from_json::val_str(String *str) Geometry_buffer buffer; String *js= args[0]->val_str_ascii(&tmp_js); uint32 srid= 0; + longlong options= 0; json_engine_t je; if ((null_value= args[0]->null_value)) return 0; - if ((arg_count == 2) && !args[1]->null_value) - srid= (uint32)args[1]->val_int(); + if (arg_count > 1 && !args[1]->null_value) + { + options= args[1]->val_int(); + if (options > 4 || options < 1) + { + String *sv= args[1]->val_str(&tmp_js); + my_error(ER_WRONG_VALUE_FOR_TYPE, MYF(0), + "option", sv->c_ptr(), "ST_GeometryFromJSON"); + null_value= 1; + return 0; + } + } + + if ((arg_count == 3) && !args[2]->null_value) + srid= (uint32)args[2]->val_int(); str->set_charset(&my_charset_bin); if (str->reserve(SRID_SIZE, 512)) @@ -148,7 +162,7 @@ String *Item_func_geometry_from_json::val_str(String *str) json_scan_start(&je, js->charset(), (const uchar *) js->ptr(), (const uchar *) js->end()); - if ((null_value= !Geometry::create_from_json(&buffer, &je, str))) + if ((null_value= !Geometry::create_from_json(&buffer, &je, options==1, str))) { int code= 0; @@ -163,6 +177,9 @@ String *Item_func_geometry_from_json::val_str(String *str) case Geometry::GEOJ_POLYGON_NOT_CLOSED: code= ER_GEOJSON_NOT_CLOSED; break; + case Geometry::GEOJ_DIMENSION_NOT_SUPPORTED: + my_error(ER_GIS_INVALID_DATA, MYF(0), "ST_GeometryFromJSON"); + break; default: report_json_error_ex(js, &je, func_name(), 0, Sql_condition::WARN_LEVEL_WARN); return NULL; diff --git a/sql/spatial.cc b/sql/spatial.cc index 7c9d8bb771e..095f7ff81db 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -339,7 +339,7 @@ Geometry *Geometry::create_from_wkb(Geometry_buffer *buffer, Geometry *Geometry::create_from_json(Geometry_buffer *buffer, - json_engine_t *je, String *res) + json_engine_t *je, bool er_on_3D, String *res) { Class_info *ci= NULL; const uchar *coord_start= NULL, *geom_start= NULL, @@ -514,14 +514,14 @@ create_geom: result= (*ci->m_create_func)(buffer->data); res->q_append((char) wkb_ndr); res->q_append((uint32) result->get_class_info()->m_type_id); - if (result->init_from_json(je, res)) + if (result->init_from_json(je, er_on_3D, res)) goto err_return; return result; handle_geometry_key: json_scan_start(je, je->s.cs, geometry_start, je->s.str_end); - return create_from_json(buffer, je, res); + return create_from_json(buffer, je, er_on_3D, res); err_return: return NULL; @@ -780,7 +780,8 @@ uint Gis_point::init_from_wkb(const char *wkb, uint len, } -static int read_point_from_json(json_engine_t *je, double *x, double *y) +static int read_point_from_json(json_engine_t *je, bool er_on_3D, + double *x, double *y) { int n_coord= 0, err; double tmp, *d; @@ -803,14 +804,17 @@ static int read_point_from_json(json_engine_t *je, double *x, double *y) n_coord++; } - return 0; + if (n_coord <= 2 || !er_on_3D) + return 0; + je->s.error= Geometry::GEOJ_DIMENSION_NOT_SUPPORTED; + return 1; bad_coordinates: je->s.error= Geometry::GEOJ_INCORRECT_GEOJSON; return 1; } -bool Gis_point::init_from_json(json_engine_t *je, String *wkb) +bool Gis_point::init_from_json(json_engine_t *je, bool er_on_3D, String *wkb) { double x, y; if (json_read_value(je)) @@ -822,7 +826,7 @@ bool Gis_point::init_from_json(json_engine_t *je, String *wkb) return TRUE; } - if (read_point_from_json(je, &x, &y) || + if (read_point_from_json(je, er_on_3D, &x, &y) || wkb->reserve(POINT_DATA_SIZE)) return TRUE; @@ -971,7 +975,8 @@ uint Gis_line_string::init_from_wkb(const char *wkb, uint len, } -bool Gis_line_string::init_from_json(json_engine_t *je, String *wkb) +bool Gis_line_string::init_from_json(json_engine_t *je, bool er_on_3D, + String *wkb) { uint32 n_points= 0; uint32 np_pos= wkb->length(); @@ -994,7 +999,7 @@ bool Gis_line_string::init_from_json(json_engine_t *je, String *wkb) { DBUG_ASSERT(je->state == JST_VALUE); - if (p.init_from_json(je, wkb)) + if (p.init_from_json(je, er_on_3D, wkb)) return TRUE; n_points++; } @@ -1364,7 +1369,7 @@ uint Gis_polygon::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, } -bool Gis_polygon::init_from_json(json_engine_t *je, String *wkb) +bool Gis_polygon::init_from_json(json_engine_t *je, bool er_on_3D, String *wkb) { uint32 n_linear_rings= 0; uint32 lr_pos= wkb->length(); @@ -1389,7 +1394,7 @@ bool Gis_polygon::init_from_json(json_engine_t *je, String *wkb) DBUG_ASSERT(je->state == JST_VALUE); uint32 ls_pos=wkb->length(); - if (ls.init_from_json(je, wkb)) + if (ls.init_from_json(je, er_on_3D, wkb)) return TRUE; ls.set_data_ptr(wkb->ptr() + ls_pos, wkb->length() - ls_pos); if (ls.is_closed(&closed) || !closed) @@ -1855,7 +1860,8 @@ uint Gis_multi_point::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, } -bool Gis_multi_point::init_from_json(json_engine_t *je, String *wkb) +bool Gis_multi_point::init_from_json(json_engine_t *je, bool er_on_3D, + String *wkb) { uint32 n_points= 0; uint32 np_pos= wkb->length(); @@ -1883,7 +1889,7 @@ bool Gis_multi_point::init_from_json(json_engine_t *je, String *wkb) wkb->q_append((char) wkb_ndr); wkb->q_append((uint32) wkb_point); - if (p.init_from_json(je, wkb)) + if (p.init_from_json(je, er_on_3D, wkb)) return TRUE; n_points++; } @@ -2123,7 +2129,8 @@ uint Gis_multi_line_string::init_from_wkb(const char *wkb, uint len, } -bool Gis_multi_line_string::init_from_json(json_engine_t *je, String *wkb) +bool Gis_multi_line_string::init_from_json(json_engine_t *je, bool er_on_3D, + String *wkb) { uint32 n_line_strings= 0; uint32 ls_pos= wkb->length(); @@ -2151,7 +2158,7 @@ bool Gis_multi_line_string::init_from_json(json_engine_t *je, String *wkb) wkb->q_append((char) wkb_ndr); wkb->q_append((uint32) wkb_linestring); - if (ls.init_from_json(je, wkb)) + if (ls.init_from_json(je, er_on_3D, wkb)) return TRUE; n_line_strings++; @@ -2511,7 +2518,8 @@ uint Gis_multi_polygon::init_from_opresult(String *bin, } -bool Gis_multi_polygon::init_from_json(json_engine_t *je, String *wkb) +bool Gis_multi_polygon::init_from_json(json_engine_t *je, bool er_on_3D, + String *wkb) { uint32 n_polygons= 0; int np_pos= wkb->length(); @@ -2539,7 +2547,7 @@ bool Gis_multi_polygon::init_from_json(json_engine_t *je, String *wkb) wkb->q_append((char) wkb_ndr); wkb->q_append((uint32) wkb_polygon); - if (p.init_from_json(je, wkb)) + if (p.init_from_json(je, er_on_3D, wkb)) return TRUE; n_polygons++; @@ -2986,7 +2994,8 @@ uint Gis_geometry_collection::init_from_wkb(const char *wkb, uint len, } -bool Gis_geometry_collection::init_from_json(json_engine_t *je, String *wkb) +bool Gis_geometry_collection::init_from_json(json_engine_t *je, bool er_on_3D, + String *wkb) { uint32 n_objects= 0; uint32 no_pos= wkb->length(); @@ -3012,7 +3021,7 @@ bool Gis_geometry_collection::init_from_json(json_engine_t *je, String *wkb) DBUG_ASSERT(je->state == JST_VALUE); - if (!(g= create_from_json(&buffer, je, wkb))) + if (!(g= create_from_json(&buffer, je, er_on_3D, wkb))) return TRUE; *je= sav_je; diff --git a/sql/spatial.h b/sql/spatial.h index 3858c0d2e51..45f335596c8 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -255,6 +255,7 @@ public: GEOJ_INCORRECT_GEOJSON= 1, GEOJ_TOO_FEW_POINTS= 2, GEOJ_POLYGON_NOT_CLOSED= 3, + GEOJ_DIMENSION_NOT_SUPPORTED= 4, }; @@ -281,7 +282,8 @@ public: virtual uint init_from_opresult(String *bin, const char *opres, uint res_len) { return init_from_wkb(opres + 4, UINT_MAX32, wkb_ndr, bin) + 4; } - virtual bool init_from_json(json_engine_t *je, String *wkb) {return true;} + virtual bool init_from_json(json_engine_t *je, bool er_on_3D, String *wkb) + { return true; } virtual bool get_data_as_wkt(String *txt, const char **end) const=0; virtual bool get_data_as_json(String *txt, uint max_dec_digits, @@ -315,8 +317,8 @@ public: bool init_stream=1); static Geometry *create_from_wkb(Geometry_buffer *buffer, const char *wkb, uint32 len, String *res); - static Geometry *create_from_json(Geometry_buffer *buffer, - json_engine_t *je, String *res); + static Geometry *create_from_json(Geometry_buffer *buffer, json_engine_t *je, + bool er_on_3D, String *res); static Geometry *create_from_opresult(Geometry_buffer *g_buf, String *res, Gcalc_result_receiver &rr); int as_wkt(String *wkt, const char **end); @@ -395,7 +397,7 @@ public: uint32 get_data_size() const; bool init_from_wkt(Gis_read_stream *trs, String *wkb); uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); - bool init_from_json(json_engine_t *je, String *wkb); + bool init_from_json(json_engine_t *je, bool er_on_3D, String *wkb); bool get_data_as_wkt(String *txt, const char **end) const; bool get_data_as_json(String *txt, uint max_dec_digits, const char **end) const; @@ -450,7 +452,7 @@ public: uint32 get_data_size() const; bool init_from_wkt(Gis_read_stream *trs, String *wkb); uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); - bool init_from_json(json_engine_t *je, String *wkb); + bool init_from_json(json_engine_t *je, bool er_on_3D, String *wkb); bool get_data_as_wkt(String *txt, const char **end) const; bool get_data_as_json(String *txt, uint max_dec_digits, const char **end) const; @@ -484,7 +486,7 @@ public: bool init_from_wkt(Gis_read_stream *trs, String *wkb); uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); uint init_from_opresult(String *bin, const char *opres, uint res_len); - bool init_from_json(json_engine_t *je, String *wkb); + bool init_from_json(json_engine_t *je, bool er_on_3D, String *wkb); bool get_data_as_wkt(String *txt, const char **end) const; bool get_data_as_json(String *txt, uint max_dec_digits, const char **end) const; @@ -521,7 +523,7 @@ public: bool init_from_wkt(Gis_read_stream *trs, String *wkb); uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); uint init_from_opresult(String *bin, const char *opres, uint res_len); - bool init_from_json(json_engine_t *je, String *wkb); + bool init_from_json(json_engine_t *je, bool er_on_3D, String *wkb); bool get_data_as_wkt(String *txt, const char **end) const; bool get_data_as_json(String *txt, uint max_dec_digits, const char **end) const; @@ -550,7 +552,7 @@ public: bool init_from_wkt(Gis_read_stream *trs, String *wkb); uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); uint init_from_opresult(String *bin, const char *opres, uint res_len); - bool init_from_json(json_engine_t *je, String *wkb); + bool init_from_json(json_engine_t *je, bool er_on_3D, String *wkb); bool get_data_as_wkt(String *txt, const char **end) const; bool get_data_as_json(String *txt, uint max_dec_digits, const char **end) const; @@ -580,7 +582,7 @@ public: uint32 get_data_size() const; bool init_from_wkt(Gis_read_stream *trs, String *wkb); uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); - bool init_from_json(json_engine_t *je, String *wkb); + bool init_from_json(json_engine_t *je, bool er_on_3D, String *wkb); bool get_data_as_wkt(String *txt, const char **end) const; bool get_data_as_json(String *txt, uint max_dec_digits, const char **end) const; @@ -612,7 +614,7 @@ public: bool init_from_wkt(Gis_read_stream *trs, String *wkb); uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); uint init_from_opresult(String *bin, const char *opres, uint res_len); - bool init_from_json(json_engine_t *je, String *wkb); + bool init_from_json(json_engine_t *je, bool er_on_3D, String *wkb); bool get_data_as_wkt(String *txt, const char **end) const; bool get_data_as_json(String *txt, uint max_dec_digits, const char **end) const; |