diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_geofunc.cc | 60 | ||||
-rw-r--r-- | sql/item_geofunc.h | 15 |
2 files changed, 60 insertions, 15 deletions
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index f65df790dfb..8cae6dd6564 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -1284,6 +1284,18 @@ int Item_func_buffer::Transporter::add_point_buffer(double x, double y) int Item_func_buffer::Transporter::start_line() { + if (buffer_op == Gcalc_function::op_difference) + { + skip_line= TRUE; + return 0; + } + + m_nshapes= 0; + + if (m_fn->reserve_op_buffer(2)) + return 1; + last_shape_pos= m_fn->get_next_operation_pos(); + m_fn->add_operation(buffer_op, 0); m_npoints= 0; int_start_line(); return 0; @@ -1292,11 +1304,25 @@ int Item_func_buffer::Transporter::start_line() int Item_func_buffer::Transporter::start_poly() { - ++m_nshapes; + m_nshapes= 1; + + if (m_fn->reserve_op_buffer(2)) + return 1; + last_shape_pos= m_fn->get_next_operation_pos(); + m_fn->add_operation(buffer_op, 0); return Gcalc_operation_transporter::start_poly(); } +int Item_func_buffer::Transporter::complete_poly() +{ + if (Gcalc_operation_transporter::complete_poly()) + return 1; + m_fn->add_operands_to_op(last_shape_pos, m_nshapes); + return 0; +} + + int Item_func_buffer::Transporter::start_ring() { m_npoints= 0; @@ -1304,8 +1330,20 @@ int Item_func_buffer::Transporter::start_ring() } +int Item_func_buffer::Transporter::start_collection(int n_objects) +{ + if (m_fn->reserve_op_buffer(1)) + return 1; + m_fn->add_operation(Gcalc_function::op_union, n_objects); + return 0; +} + + int Item_func_buffer::Transporter::add_point(double x, double y) { + if (skip_line) + return 0; + if (m_npoints && x == x2 && y == y2) return 0; @@ -1374,9 +1412,14 @@ int Item_func_buffer::Transporter::complete() int Item_func_buffer::Transporter::complete_line() { - if (complete()) - return 1; - int_complete_line(); + if (!skip_line) + { + if (complete()) + return 1; + int_complete_line(); + m_fn->add_operands_to_op(last_shape_pos, m_nshapes); + } + skip_line= FALSE; return 0; } @@ -1396,7 +1439,6 @@ String *Item_func_buffer::val_str(String *str_value) double dist= args[1]->val_real(); Geometry_buffer buffer; Geometry *g; - uint32 union_pos; uint32 srid= 0; String *str_result= NULL; Transporter trn(&func, &collector, dist); @@ -1418,17 +1460,9 @@ String *Item_func_buffer::val_str(String *str_value) goto mem_error; } - if (func.reserve_op_buffer(2)) - goto mem_error; - /* will specify operands later */ - union_pos= func.get_next_operation_pos(); - func.add_operation((dist > 0.0) ? Gcalc_function::op_union : - Gcalc_function::op_difference, 0); - if (g->store_shapes(&trn)) goto mem_error; - func.add_operands_to_op(union_pos, trn.m_nshapes); collector.prepare_operation(); if (func.alloc_states()) goto mem_error; diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index 1838a3783e8..d5ed2c1f764 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -26,6 +26,7 @@ #endif #include "gcalc_slicescan.h" +#include "gcalc_tools.h" class Item_geometry_func: public Item_str_func { @@ -298,18 +299,28 @@ protected: int add_last_edge_buffer(); int add_point_buffer(double x, double y); int complete(); - public: int m_nshapes; + Gcalc_function::op_type buffer_op; + int last_shape_pos; + bool skip_line; + + public: Transporter(Gcalc_function *fn, Gcalc_heap *heap, double d) : - Gcalc_operation_transporter(fn, heap), m_npoints(0), m_d(d), m_nshapes(0) + Gcalc_operation_transporter(fn, heap), m_npoints(0), m_d(d), + m_nshapes(0), buffer_op((d > 0.0) ? Gcalc_function::op_union : + Gcalc_function::op_difference), + skip_line(FALSE) {} int single_point(double x, double y); int start_line(); int complete_line(); int start_poly(); + int complete_poly(); int start_ring(); int complete_ring(); int add_point(double x, double y); + + int start_collection(int n_objects); }; Gcalc_heap collector; Gcalc_function func; |