List:Commits« Previous MessageNext Message »
From:Alexey Botchkov Date:November 24 2009 4:37pm
Subject:bzr commit into mysql-5.1-bugteam branch (holyfoot:2663) Bug#46372
View as plain text  
#At file:///home/hf/work/mysql_common/gis-bugfix/ based on revid:holyfoot@stripped

 2663 Alexey Botchkov	2009-11-24
      Bug#46372 buffer of linestring returns multipolygon in certain cases 
         mistake in the algorithm - dx_dy parameter should be just dx if
         dy is 0.
      
      per-file comments:
        sql/gcalc_slicescan.cc
      Bug#46372 buffer of linestring returns multipolygon in certain cases 
           GET_DX_DY fixed
        sql/gcalc_slicescan.h
      Bug#46372 buffer of linestring returns multipolygon in certain cases 
           some debugging features added
        sql/item_geofunc.cc
      Bug#46372 buffer of linestring returns multipolygon in certain cases 
           debugging code added

    modified:
      sql/gcalc_slicescan.cc
      sql/gcalc_slicescan.h
      sql/item_geofunc.cc
=== modified file 'sql/gcalc_slicescan.cc'
--- a/sql/gcalc_slicescan.cc	2009-05-12 15:19:33 +0000
+++ b/sql/gcalc_slicescan.cc	2009-11-24 16:35:34 +0000
@@ -4,6 +4,79 @@
 
 #include "gcalc_slicescan.h"
 
+#ifdef GCALC_DBUG
+void gcalc_dbug_env_struct::start_line()
+{
+  if (recfile)
+  {
+    fprintf(recfile, "LINESTRING(");
+    first_point= 1;
+  }
+}
+
+
+void gcalc_dbug_env_struct::start_ring()
+{
+  if (recfile)
+  {
+    fprintf(recfile, "RING(");
+    first_point= 1;
+  }
+}
+
+
+void gcalc_dbug_env_struct::complete()
+{
+  if (recfile)
+  {
+    fprintf(recfile, ")\n");
+    fflush(recfile);
+  }
+}
+
+
+void gcalc_dbug_env_struct::add_point(double x, double y)
+{
+  if (recfile)
+  {
+    if (!first_point)
+      fprintf(recfile, ", ");
+    else
+      first_point=0;
+    fprintf(recfile, "%.15g %.15g", x, y);
+  }
+}
+
+
+void gcalc_dbug_env_struct::start_newfile(const char *filename)
+{
+  recfile= fopen(filename, "w");
+}
+
+
+void gcalc_dbug_env_struct::start_append(const char *filename)
+{
+  recfile= fopen(filename, "a");
+}
+
+
+void gcalc_dbug_env_struct::stop_recording()
+{
+  fclose(recfile);
+  recfile= NULL;
+}
+
+gcalc_dbug_env_struct::~gcalc_dbug_env_struct()
+{
+  if (recfile)
+    fclose(recfile);
+}
+
+static gcalc_dbug_env_struct gcalc_dbug_usual_env;
+gcalc_dbug_env_struct *gcalc_dbug_cur_env= &gcalc_dbug_usual_env;
+
+#endif /*GCLAC_DBUG*/
+
 #define PH_DATA_OFFSET 8
 #define coord_to_float(d) ((double) d)
 
@@ -167,8 +240,9 @@ inline int GET_DX_DY(double *dxdy,
                      const gcalc_heap::info *p0, const gcalc_heap::info *p1)
 {
   double dy= p1->y - p0->y;
+  *dxdy= p1->x - p0->x;
   return (dy == 0.0) ||
-         (*dxdy= (p1->x - p0->x)/dy)>DBL_MAX ||
+         (*dxdy/= dy)>DBL_MAX ||
          (*dxdy)<-DBL_MAX;
 }
 

=== modified file 'sql/gcalc_slicescan.h'
--- a/sql/gcalc_slicescan.h	2009-05-13 07:03:17 +0000
+++ b/sql/gcalc_slicescan.h	2009-11-24 16:35:34 +0000
@@ -1,6 +1,41 @@
 #ifndef gcalc_slicescan_h
 #define gcalc_slicescan_h
 
+/* #define GCALC_DBUG */
+
+#ifdef GCALC_DBUG
+class gcalc_dbug_env_struct
+{
+  FILE *recfile;
+  bool first_point;
+public:
+  gcalc_dbug_env_struct() : recfile(NULL) {}
+  virtual void start_ring();
+  virtual void start_line();
+  virtual void add_point(double x, double y);
+  virtual void complete();
+  
+  void start_newfile(const char *filename);
+  void start_append(const char *filename);
+  void stop_recording();
+  virtual ~gcalc_dbug_env_struct();
+};
+
+extern gcalc_dbug_env_struct *gcalc_dbug_cur_env;
+#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_STARTFILE(FILENAME) gcalc_dbug_cur_env->start_newfile(FILENAME)
+#define GCALC_DBUG_STOP gcalc_dbug_cur_env->stop_recording()
+#else
+#define GCALC_DBUG_START_RING
+#define GCALC_DBUG_ADD_POINT(X,Y)
+#define GCALC_DBUG_COMPLETE
+#define GCALC_DBUG_STARTFILE(FILENAME)
+#define GCALC_DBUG_STOP
+#endif /*GCLAC_DBUG*/
+
 class gcalc_dyn_list
 {
 public:
@@ -137,6 +172,7 @@ public:
     m_shape_info= info;
     m_first= m_prev= NULL;
     m_line_flag= TRUE;
+    GCALC_DBUG_START_LINE;
   }
 
   void start_ring(gcalc_shape_info info)
@@ -144,6 +180,7 @@ public:
     m_shape_info= info;
     m_first= m_prev= NULL;
     m_line_flag= FALSE;
+    GCALC_DBUG_START_RING;
   }
 
   int add_point(double x, double y)
@@ -162,6 +199,7 @@ public:
     else
       m_first= point;
     m_prev= point;
+    GCALC_DBUG_ADD_POINT(x, y);
     return 0;
   }
 
@@ -181,6 +219,7 @@ public:
 	m_prev->left= m_first;
       }
     }
+    GCALC_DBUG_COMPLETE;
   }
 };
 

=== modified file 'sql/item_geofunc.cc'
--- a/sql/item_geofunc.cc	2009-11-18 13:40:52 +0000
+++ b/sql/item_geofunc.cc	2009-11-24 16:35:34 +0000
@@ -885,6 +885,12 @@ static int fill_gap(gcalc_shape_transpor
 }
 
 
+/*
+  Calculates the vector (p2,p1) and
+  negatively orthogonal to it with the length of d.
+  The result is (ex,ey) - the vector, (px,py) - the orthogonal.
+*/
+
 static void calculate_perpendicular(const gcalc_heap::info *p1,
                                     const gcalc_heap::info *p2, double d,
                                     double *ex, double *ey,
@@ -977,7 +983,7 @@ int Item_func_buffer::add_last_edge_buff
   if (trn.add_point(p1->x + p1_x, p1->y + p1_y) ||
       trn.add_point(p1->x - p1_x, p1->y - p1_y) ||
       trn.add_point(p2->x - p1_x, p2->y - p1_y) ||
-      fill_half_circle(&trn, p2->x, p2->y, p1_x, p1_y) ||
+      fill_half_circle(&trn, p2->x, p2->y, -p1_x, -p1_y) ||
       trn.add_point(p2->x + p1_x, p2->y + p1_y))
     return 1;
   trn.complete();
@@ -1107,6 +1113,7 @@ String *Item_func_buffer::val_str(String
   func.add_operation((dist > 0.0) ? gcalc_function::op_union :
                                     gcalc_function::op_difference, 2);
 
+  GCALC_DBUG_STARTFILE("/home/hf/linebuffer");
   if (g->store_shapes(&collector, &func))
     goto mem_error;
 
@@ -1141,6 +1148,7 @@ String *Item_func_buffer::val_str(String
       break;
     dist_point= dist_point->get_next();
   }
+  GCALC_DBUG_STOP;
   func.add_operands_to_op(union_pos, n_operands);
   collector.prepare_operation();
   if (func.alloc_states())


Attachment: [text/bzr-bundle] bzr/holyfoot@mysql.com-20091124163534-hywby4go5483txcn.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (holyfoot:2663) Bug#46372Alexey Botchkov25 Nov