#At file:///home/hf/work/mysql_common/gis-bugfix/ based on revid:holyfoot@stripped
2664 Alexey Botchkov 2009-12-04
Bug#46372 buffer of linestring returns multipolygon in certain cases
there was a mistake in handling of 'holes' in the polygons.
Fixed by adding the 'first_poly_node' pointer to the res_point
structure to point to the first point of the surrounding polygon.
Also a set of debugging functions was added. It doesn't affect the
working fucntions, but greatly simplifies the debugging.
This path fixes also bug#46498 and bug#45883 also.
per-file comments:
sql/gcalc_slicescan.cc
Bug#46372 buffer of linestring returns multipolygon in certain cases
sql/gcalc_slicescan.h
Bug#46372 buffer of linestring returns multipolygon in certain cases
sql/gcalc_tools.cc
Bug#46372 buffer of linestring returns multipolygon in certain cases
sql/gcalc_tools.h
Bug#46372 buffer of linestring returns multipolygon in certain cases
sql/item_geofunc.cc
Bug#46372 buffer of linestring returns multipolygon in certain cases
sql/spatial.cc
Bug#46372 buffer of linestring returns multipolygon in certain cases
modified:
sql/gcalc_slicescan.cc
sql/gcalc_slicescan.h
sql/gcalc_tools.cc
sql/gcalc_tools.h
sql/item_geofunc.cc
sql/spatial.cc
=== modified file 'sql/gcalc_slicescan.cc'
--- a/sql/gcalc_slicescan.cc 2009-11-24 16:35:34 +0000
+++ b/sql/gcalc_slicescan.cc 2009-12-04 14:30:55 +0000
@@ -66,12 +66,45 @@ void gcalc_dbug_env_struct::stop_recordi
recfile= NULL;
}
+
+void gcalc_dbug_env_struct::print(const char *ln)
+{
+ if (recfile)
+ fprintf(recfile, "%s", ln);
+}
+
+
gcalc_dbug_env_struct::~gcalc_dbug_env_struct()
{
if (recfile)
fclose(recfile);
}
+
+void gcalc_dbug_do_print(const char* fmt, ...)
+{
+ va_list args;
+ char buff[1000];
+ va_start(args, fmt);
+ vsnprintf(buff, sizeof(buff), fmt, args);
+ va_end(args);
+ gcalc_dbug_cur_env->print(buff);
+}
+
+
+void gcalc_scan_iterator::point::dbug_print()
+{
+ const gcalc_scan_iterator::point *slice= this;
+ for (; slice; slice= slice->get_next())
+ {
+ gcalc_dbug_do_print("(%d %.15g ", slice->thread, slice->x);
+ gcalc_dbug_do_print(slice->horiz_dir ? "-" : "/");
+ gcalc_dbug_do_print(" %.15g) ", slice->dx_dy);
+ }
+ gcalc_dbug_do_print("\n");
+}
+
+
static gcalc_dbug_env_struct gcalc_dbug_usual_env;
gcalc_dbug_env_struct *gcalc_dbug_cur_env= &gcalc_dbug_usual_env;
@@ -219,6 +252,18 @@ void gcalc_heap::prepare_operation()
trim_node(cur->left, cur);
trim_node(cur->right, cur);
}
+#ifdef GCALC_DBUG
+ {
+ info *cur= get_first();
+ GCALC_DBUG_PRINT(("shape\t x\t y\tleft\tright\tthis\n"));
+ for (; cur; cur= cur->get_next())
+ {
+ GCALC_DBUG_PRINT(("%d\t%.15g\t%.15g\t %d\t %d\t %d\n", cur->shape,
+ cur->x, cur->y,(int)cur->left, (int)cur->right, (int) cur));
+ }
+ GCALC_DBUG_PRINT(("------------------\n"));
+ }
+#endif /*GCALC_DBUG*/
}
@@ -299,7 +344,7 @@ static bool slice_first_equal_x(const gc
const gcalc_scan_iterator::point *p1)
{
if (p0->horiz_dir == p1->horiz_dir)
- return p0->dx_dy < p1->dx_dy;
+ return p0->dx_dy <= p1->dx_dy;
if (p0->horiz_dir)
return p0->dx_dy < 0;
return p1->dx_dy > 0; /* p1->horiz_dir case */
@@ -494,6 +539,12 @@ int gcalc_scan_iterator::normal_scan()
free_list(sp1);
}
+ GCALC_DBUG_PRINT(("Y%.15g", m_y0));
+ GCALC_DBUG_SLICE(m_slice0);
+ GCALC_DBUG_PRINT(("Y%.15g", m_y1));
+ GCALC_DBUG_SLICE(m_slice1);
+ GCALC_DBUG_PRINT(("\n"));
+
if (intersections_found)
return handle_intersections();
@@ -589,6 +640,7 @@ int gcalc_scan_iterator::find_intersecti
} while (intersections_found);
*hook= NULL;
+ GCALC_DBUG_PRINT(("intersections found:%d\n", m_n_intersections));
return 0;
}
@@ -684,6 +736,11 @@ int gcalc_scan_iterator::intersection_sc
free_list(m_slice1);
m_slice1= m_sav_slice;
free_list(m_intersections);
+ GCALC_DBUG_PRINT((" is Y%.15g", m_y0));
+ GCALC_DBUG_SLICE(m_slice0);
+ GCALC_DBUG_PRINT((" is Y%.15g", m_y1));
+ GCALC_DBUG_SLICE(m_slice1);
+ GCALC_DBUG_PRINT(("\n"));
return 0;
}
}
@@ -715,6 +772,7 @@ redo_loop:
there's two intersections with the same Y
Move suitable one to the beginning of the list
*/
+ GCALC_DBUG_PRINT(("redo_loop needed\n"));
pop_suitable_intersection();
goto redo_loop;
}
@@ -747,6 +805,11 @@ redo_loop:
*psp1= NULL;
}
+ GCALC_DBUG_PRINT((" is Y%.15g", m_y0));
+ GCALC_DBUG_SLICE(m_slice0);
+ GCALC_DBUG_PRINT((" is Y%.15g", m_y1));
+ GCALC_DBUG_SLICE(m_slice1);
+ GCALC_DBUG_PRINT(("\n"));
return 0;
}
=== modified file 'sql/gcalc_slicescan.h'
--- a/sql/gcalc_slicescan.h 2009-11-24 16:35:34 +0000
+++ b/sql/gcalc_slicescan.h 2009-12-04 14:30:55 +0000
@@ -1,7 +1,7 @@
#ifndef gcalc_slicescan_h
#define gcalc_slicescan_h
-/* #define GCALC_DBUG */
+/*#define GCALC_DBUG*/
#ifdef GCALC_DBUG
class gcalc_dbug_env_struct
@@ -14,6 +14,7 @@ public:
virtual void start_line();
virtual void add_point(double x, double y);
virtual void complete();
+ virtual void print(const char *ln);
void start_newfile(const char *filename);
void start_append(const char *filename);
@@ -22,18 +23,24 @@ public:
};
extern gcalc_dbug_env_struct *gcalc_dbug_cur_env;
+void gcalc_dbug_do_print(const char* fmt, ...);
#define GCALC_DBUG_START_RING gcalc_dbug_cur_env->start_ring()
#define GCALC_DBUG_START_LINE gcalc_dbug_cur_env->start_line()
#define GCALC_DBUG_ADD_POINT(X,Y) gcalc_dbug_cur_env->add_point(X,Y)
#define GCALC_DBUG_COMPLETE gcalc_dbug_cur_env->complete()
+#define GCALC_DBUG_SLICE(SLICE) SLICE->dbug_print()
#define GCALC_DBUG_STARTFILE(FILENAME) gcalc_dbug_cur_env->start_newfile(FILENAME)
#define GCALC_DBUG_STOP gcalc_dbug_cur_env->stop_recording()
+#define GCALC_DBUG_PRINT(ARGLIST) gcalc_dbug_do_print ARGLIST
#else
#define GCALC_DBUG_START_RING
+#define GCALC_DBUG_START_LINE
#define GCALC_DBUG_ADD_POINT(X,Y)
#define GCALC_DBUG_COMPLETE
+#define GCALC_DBUG_SLICE(SLICE)
#define GCALC_DBUG_STARTFILE(FILENAME)
#define GCALC_DBUG_STOP
+#define GCALC_DBUG_PRINT(ARGLIST)
#endif /*GCLAC_DBUG*/
class gcalc_dyn_list
@@ -268,6 +275,9 @@ public:
next_pi= from->next_pi;
thread= from->thread;
}
+#ifdef GCALC_DBUG
+ void dbug_print();
+#endif /*GCALC_DBUG*/
};
class intersection : public gcalc_dyn_list::item
=== modified file 'sql/gcalc_tools.cc'
--- a/sql/gcalc_tools.cc 2009-05-13 07:03:17 +0000
+++ b/sql/gcalc_tools.cc 2009-12-04 14:30:55 +0000
@@ -82,26 +82,29 @@ int gcalc_function::count_internal()
result= count_internal();
while (--n_ops)
+ {
+ int next_res= count_internal();
switch (next_func)
{
case op_union:
- result= result || count_internal();
+ result= result | next_res;
break;
case op_intersection:
- result= result && count_internal();
+ result= result & next_res;
break;
case op_symdifference:
- result= result ^ count_internal();
+ result= result ^ next_res;
break;
case op_difference:
- result= result && !count_internal();
+ result= result & !next_res;
break;
case op_backdifference:
- result= !result && count_internal();
+ result= !result & next_res;
break;
default:
DBUG_ASSERT(FALSE);
};
+ }
return result ^ mask;
}
@@ -161,48 +164,102 @@ int gcalc_result_receiver::start_shape(g
{
if (buffer.reserve(4*2, 512))
return 1;
- buffer.q_append((uint32) shape);
- if (shape != gcalc_function::shape_point)
- {
- n_points_pos= buffer.length();
- buffer.length(buffer.length() + 4);
- n_points= 0;
- }
+ cur_shape= shape;
+ shape_pos= buffer.length();
+ buffer.length(shape_pos + ((shape == gcalc_function::shape_point) ? 4:8));
+ n_points= 0;
- if (!n_shapes++)
- common_shapetype= shape;
- else if (!collection_result && (shape != common_shapetype))
- {
- if (shape == gcalc_function::shape_hole)
- ++n_holes;
- else
- collection_result= TRUE;
- }
return 0;
}
int gcalc_result_receiver::add_point(double x, double y)
{
+ if (n_points && x == prev_x && y == prev_y)
+ {
+ GCALC_DBUG_PRINT(("Skip same point %.15g\t%.15g\n", x, y));
+ return 0;
+ }
+
+ GCALC_DBUG_PRINT(("Add result point %.15g\t%.15g\n", x, y));
+ if (!n_points++)
+ {
+ prev_x= first_x= x;
+ prev_y= first_y= y;
+ return 0;
+ }
+
if (buffer.reserve(8*2, 512))
return 1;
- buffer.q_append(x);
- buffer.q_append(y);
- n_points++;
+ buffer.q_append(prev_x);
+ buffer.q_append(prev_y);
+ prev_x= x;
+ prev_y= y;
return 0;
}
int gcalc_result_receiver::complete_shape()
{
- buffer.write_at_position(n_points_pos, n_points);
+ if (n_points == 0)
+ {
+ buffer.length(shape_pos);
+ return 0;
+ }
+ if (n_points == 1)
+ {
+ if (cur_shape != gcalc_function::shape_point)
+ {
+ cur_shape= gcalc_function::shape_point;
+ buffer.length(buffer.length()-4);
+ }
+ }
+ else
+ {
+ DBUG_ASSERT(cur_shape != gcalc_function::shape_point);
+ if ((cur_shape == gcalc_function::shape_polygon ||
+ cur_shape == gcalc_function::shape_hole) &&
+ prev_x == first_x && prev_y == first_y)
+ {
+ n_points--;
+ buffer.write_at_position(shape_pos+4, n_points);
+ goto do_complete;
+ }
+ buffer.write_at_position(shape_pos+4, n_points);
+ }
+
+ if (buffer.reserve(8*2, 512))
+ return 1;
+ buffer.q_append(prev_x);
+ buffer.q_append(prev_y);
+
+do_complete:
+ GCALC_DBUG_PRINT(("Complete shape %d\n", n_points));
+
+ buffer.write_at_position(shape_pos, (uint32) cur_shape);
+
+ if (!n_shapes++)
+ {
+ DBUG_ASSERT(cur_shape != gcalc_function::shape_hole);
+ common_shapetype= cur_shape;
+ }
+ else if (cur_shape == gcalc_function::shape_hole)
+ {
+ ++n_holes;
+ }
+ else if (!collection_result && (cur_shape != common_shapetype))
+ {
+ collection_result= true;
+ }
return 0;
}
int gcalc_result_receiver::single_point(double x, double y)
{
- return start_shape(gcalc_function::shape_point) || add_point(x, y);
+ return start_shape(gcalc_function::shape_point) ||
+ add_point(x, y) ||
+ complete_shape();
}
@@ -230,7 +287,7 @@ int gcalc_result_receiver::get_result_ty
switch (common_shapetype)
{
case gcalc_function::shape_polygon:
- return (get_nshapes() == 1) ?
+ return (n_shapes - n_holes == 1) ?
Geometry::wkb_polygon : Geometry::wkb_multipolygon;
case gcalc_function::shape_point:
return (n_shapes == 1) ? Geometry::wkb_point : Geometry::wkb_multipoint;
@@ -244,21 +301,26 @@ int gcalc_result_receiver::get_result_ty
}
-int gcalc_result_receiver::move_hole(uint32 dest_position, uint32 source_position)
+int gcalc_result_receiver::move_hole(uint32 dest_position, uint32 source_position,
+ uint32 *new_dest_position)
{
char *ptr;
int source_len;
if (dest_position == source_position)
+ {
+ *new_dest_position= position();
return 0;
+ }
- if (buffer.reserve(source_position - dest_position))
+ source_len= buffer.length() - source_position;
+ if (buffer.reserve(source_len, MY_ALIGN(source_len, 512)))
return 1;
+
ptr= (char *) buffer.ptr();
- source_len= buffer.length() - source_position;
- memcpy(ptr + buffer.length(), ptr + source_position, source_len);
memmove(ptr + dest_position + source_len, ptr + dest_position,
- source_position - dest_position);
+ buffer.length() - dest_position);
memcpy(ptr + dest_position, ptr + buffer.length(), source_len);
+ *new_dest_position= dest_position + source_len;
return 0;
}
@@ -300,6 +362,8 @@ inline int gcalc_operation_reducer::cont
rp->intersection_point= false;
rp->pi= p;
t->rp= rp;
+ GCALC_DBUG_PRINT(("Cont_range %d\t%d\t%.15g\t%.15g\n", (int) t,
+ (int) p->shape, p->x, p->y));
return 0;
}
@@ -320,6 +384,8 @@ inline int gcalc_operation_reducer::cont
rp->pi= p;
rp->y= y;
t->rp= rp;
+ GCALC_DBUG_PRINT(("Cont_i_range %d\t%d\t%.15g\t%.15g\n", (int) t,
+ (int) p->shape, p->x, p->y));
return 0;
}
@@ -334,6 +400,8 @@ inline int gcalc_operation_reducer::star
rp->pi= p;
t->result_range= 1;
t->rp= rp;
+ GCALC_DBUG_PRINT(("Start_range %d\t%d\t%.15g\t%.15g\n", (int) t,
+ (int) p->shape, p->x, p->y));
return 0;
}
@@ -351,6 +419,8 @@ inline int gcalc_operation_reducer::star
rp->pi= p;
t->result_range= 1;
t->rp= rp;
+ GCALC_DBUG_PRINT(("Start_i_range %d\t%d\t%.15g\t%.15g\n", (int) t,
+ (int) p->shape, p->x, p->y));
return 0;
}
@@ -366,6 +436,8 @@ inline int gcalc_operation_reducer::end_
rp->pi= p;
t->rp->up= rp;
t->result_range= 0;
+ GCALC_DBUG_PRINT(("End_range %d\t%d\t%.15g\t%.15g\n", (int) t,
+ (int) p->shape, p->x, p->y));
return 0;
}
@@ -384,6 +456,8 @@ inline int gcalc_operation_reducer::end_
rp->y= y;
t->rp->up= rp;
t->result_range= 0;
+ GCALC_DBUG_PRINT(("End_i_range %d\t%d\t%.15g\t%.15g\n", (int) t,
+ (int) p->shape, p->x, p->y));
return 0;
}
@@ -411,6 +485,9 @@ int gcalc_operation_reducer::start_coupl
rp0->outer_poly= 0;
t0->thread_start= rp0;
}
+ GCALC_DBUG_PRINT(("Start_couple t0 %d\tt1 %d\tshape %d\t%.15g\t%.15g\t%d\n",
+ (int) t0, (int) t1, (int) p->shape, p->x, p->y,
+ (int) prev_range));
return 0;
}
@@ -444,6 +521,9 @@ int gcalc_operation_reducer::start_i_cou
rp0->outer_poly= 0;
t0->thread_start= rp0;
}
+ GCALC_DBUG_PRINT(("Start_i_couple t0 %d\tt1 %d\tshape0 %d\tshape1 %d\t%.15g\t%.15g\t%d\n",
+ (int) t0, (int) t1, (int) p0->shape, (int) p1->shape, x, y,
+ (int) prev_range));
return 0;
}
@@ -464,6 +544,8 @@ int gcalc_operation_reducer::end_couple(
rp0->intersection_point= rp1->intersection_point= false;
rp0->pi= rp1->pi= p;
t0->result_range= t1->result_range= 0;
+ GCALC_DBUG_PRINT(("End_couple t0 %d\tt1 %d\tshape %d\t%.15g\t%.15g\n",
+ (int) t0, (int) t1, (int) p->shape, p->x, p->y));
return 0;
}
@@ -488,6 +570,8 @@ int gcalc_operation_reducer::end_i_coupl
t0->result_range= t1->result_range= 0;
t0->rp->up= rp0;
t1->rp->up= rp1;
+ GCALC_DBUG_PRINT(("End_i_couple t0 %d\tt1 %d\tshape0 %d\tshape1 %d\t%.15g\t%.15g\n",
+ (int) t0, (int) t1, (int) p0->shape, (int) p1->shape, x, y));
return 0;
}
@@ -501,6 +585,8 @@ int gcalc_operation_reducer::add_single_
rp->pi= p;
rp->x= p->x;
rp->y= p->y;
+ GCALC_DBUG_PRINT(("Single point shape %d\t%.15g\t%.15g\n",
+ (int) p->shape, p->x, p->y));
return 0;
}
@@ -515,6 +601,8 @@ int gcalc_operation_reducer::add_i_singl
rp->x= x;
rp->pi= p;
rp->y= y;
+ GCALC_DBUG_PRINT(("i_Single point shape %d\t%.15g\t%.15g\n",
+ (int) p->shape, x, y));
return 0;
}
@@ -833,25 +921,31 @@ inline int gcalc_operation_reducer::get_
}
-inline int gcalc_operation_reducer::get_result_thread(res_point *cur,
- gcalc_result_receiver *storage,
- int move_upward)
+int gcalc_operation_reducer::get_result_thread(res_point *cur,
+ gcalc_result_receiver *storage,
+ int move_upward)
{
res_point *next;
bool glue_step= false;
+ res_point *first_poly_node= cur;
+ double x, y;
+ GCALC_DBUG_PRINT(("Result thread \n"));
while (cur)
{
if (!glue_step)
{
if (cur->intersection_point)
{
- if (storage->add_point(float_to_coord(cur->x),
- float_to_coord(cur->y)))
- return 1;
+ x= float_to_coord(cur->x);
+ y= float_to_coord(cur->y);
}
else
- if (storage->add_point(cur->pi->x, cur->pi->y))
- return 1;
+ {
+ x= cur->pi->x;
+ y= cur->pi->y;
+ }
+ if (storage->add_point(x, y))
+ return 1;
}
next= move_upward ? cur->up : cur->down;
@@ -865,6 +959,8 @@ inline int gcalc_operation_reducer::get_
}
else
glue_step= false;
+
+ cur->first_poly_node= first_poly_node;
free_result(cur);
cur= next;
}
@@ -872,18 +968,19 @@ inline int gcalc_operation_reducer::get_
}
-inline int gcalc_operation_reducer::get_polygon_result(res_point *cur,
- gcalc_result_receiver *storage)
+int gcalc_operation_reducer::get_polygon_result(res_point *cur,
+ gcalc_result_receiver *storage)
{
res_point *glue= cur->glue;
glue->up->down= NULL;
free_result(glue);
- return get_result_thread(cur, storage, 1);
+ return get_result_thread(cur, storage, 1) ||
+ storage->complete_shape();
}
-inline int gcalc_operation_reducer::get_line_result(res_point *cur,
- gcalc_result_receiver *storage)
+int gcalc_operation_reducer::get_line_result(res_point *cur,
+ gcalc_result_receiver *storage)
{
res_point *next;
int move_upward= 1;
@@ -904,17 +1001,20 @@ inline int gcalc_operation_reducer::get_
}
}
- return get_result_thread(cur, storage, move_upward);
+ return get_result_thread(cur, storage, move_upward) ||
+ storage->complete_shape();
}
int gcalc_operation_reducer::get_result(gcalc_result_receiver *storage)
{
+ GCALC_DBUG_PRINT(("get_result\n"));
*m_res_hook= NULL;
while (m_result)
{
if (!m_result->up)
{
+ GCALC_DBUG_PRINT(("singlet\n"));
if (get_single_result(m_result, storage))
return 1;
continue;
@@ -922,19 +1022,24 @@ int gcalc_operation_reducer::get_result(
gcalc_function::shape_type shape= m_fn->get_shape_kind(m_result->pi->shape);
if (shape == gcalc_function::shape_polygon)
{
+ GCALC_DBUG_PRINT(("Polygon result \n"));
if (m_result->outer_poly)
{
- uint32 insert_position, hole_position;
- insert_position= m_result->outer_poly->poly_position;
+ uint32 *insert_position, hole_position;
+ GCALC_DBUG_PRINT(("\tOuter poly \n"));
+ insert_position= &m_result->outer_poly->first_poly_node->poly_position;
+ DBUG_ASSERT(*insert_position);
hole_position= storage->position();
storage->start_shape(gcalc_function::shape_hole);
if (get_polygon_result(m_result, storage) ||
- storage->move_hole(insert_position, hole_position))
+ storage->move_hole(*insert_position, hole_position,
+ insert_position))
return 1;
}
else
{
uint32 *poly_position= &m_result->poly_position;
+ GCALC_DBUG_PRINT(("\tNo outer poly \n"));
storage->start_shape(gcalc_function::shape_polygon);
if (get_polygon_result(m_result, storage))
return 1;
@@ -943,12 +1048,11 @@ int gcalc_operation_reducer::get_result(
}
else
{
+ GCALC_DBUG_PRINT(("Line result \n"));
storage->start_shape(shape);
if (get_line_result(m_result, storage))
return 1;
}
- if (storage->complete_shape())
- return 1;
}
m_res_hook= (gcalc_dyn_list::item **)&m_result;
=== modified file 'sql/gcalc_tools.h'
--- a/sql/gcalc_tools.h 2009-04-13 08:03:25 +0000
+++ b/sql/gcalc_tools.h 2009-12-04 14:30:55 +0000
@@ -71,12 +71,15 @@ public:
class gcalc_result_receiver
{
String buffer;
- uint32 n_points_pos;
uint32 n_points;
gcalc_function::shape_type common_shapetype;
bool collection_result;
uint32 n_shapes;
uint32 n_holes;
+
+ gcalc_function::shape_type cur_shape;
+ uint32 shape_pos;
+ double first_x, first_y, prev_x, prev_y;
public:
gcalc_result_receiver();
int start_shape(gcalc_function::shape_type shape);
@@ -92,7 +95,8 @@ public:
int get_nholes() { return n_holes; }
int get_result_typeid();
uint32 position() { return buffer.length(); }
- int move_hole(uint32 dest_position, uint32 source_position);
+ int move_hole(uint32 dest_position, uint32 source_position,
+ uint32 *new_dest_position);
};
@@ -122,13 +126,17 @@ public:
public:
bool intersection_point;
double x,y;
- const gcalc_heap::info *pi;
res_point *up;
res_point *down;
res_point *glue;
union
{
- const res_point *outer_poly;
+ const gcalc_heap::info *pi;
+ res_point *first_poly_node;
+ };
+ union
+ {
+ res_point *outer_poly;
uint32 poly_position;
};
gcalc_dyn_list::item **prev_hook;
@@ -140,7 +148,7 @@ public:
public:
res_point *rp;
int result_range;
- const res_point *thread_start;
+ res_point *thread_start;
active_thread *get_next() { return (active_thread *)next; }
};
@@ -207,7 +215,7 @@ private:
int get_single_result(res_point *res, gcalc_result_receiver *storage);
int get_result_thread(res_point *cur, gcalc_result_receiver *storage,
int move_upward);
- int get_polygon_result(res_point *cur,gcalc_result_receiver *storage);
+ int get_polygon_result(res_point *cur, gcalc_result_receiver *storage);
int get_line_result(res_point *cur, gcalc_result_receiver *storage);
void free_result(res_point *res);
=== modified file 'sql/item_geofunc.cc'
--- a/sql/item_geofunc.cc 2009-11-24 16:35:34 +0000
+++ b/sql/item_geofunc.cc 2009-12-04 14:30:55 +0000
@@ -737,6 +737,8 @@ String *Item_func_spatial_operation::val
goto exit;
+ GCALC_DBUG_STARTFILE("/home/hf/gcalc_log");
+
collector.prepare_operation();
scan_it.init(&collector);
if (func.alloc_states())
@@ -759,6 +761,7 @@ String *Item_func_spatial_operation::val
goto exit;
exit:
+ GCALC_DBUG_STOP;
collector.reset();
func.reset();
scan_it.reset();
=== modified file 'sql/spatial.cc'
--- a/sql/spatial.cc 2009-11-18 13:40:52 +0000
+++ b/sql/spatial.cc 2009-12-04 14:30:55 +0000
@@ -1757,6 +1757,8 @@ uint Gis_multi_polygon::init_from_opresu
const char *opres_orig= opres;
uint p_len;
uint poly_shapes;
+ uint n_poly= 0;
+ uint32 np_pos= bin->length();
if (bin->reserve(4, 512))
return 0;
@@ -1772,7 +1774,9 @@ uint Gis_multi_polygon::init_from_opresu
return 0;
n_shapes-= poly_shapes;
opres+= p_len;
+ n_poly++;
}
+ bin->write_at_position(np_pos, n_poly);
return opres - opres_orig;
}
Attachment: [text/bzr-bundle] bzr/holyfoot@mysql.com-20091204143055-0s3xwff43g3oiuuy.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1-bugteam branch (holyfoot:2664) Bug#45883Bug#46372 Bug#46498 | Alexey Botchkov | 5 Dec |