MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
item_geofunc.h
1 #ifndef ITEM_GEOFUNC_INCLUDED
2 #define ITEM_GEOFUNC_INCLUDED
3 
4 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; version 2 of the License.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software Foundation,
17  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
18 
19 
20 /* This file defines all spatial functions */
21 
22 #ifdef HAVE_SPATIAL
23 
24 #include "gcalc_slicescan.h"
25 
26 class Item_geometry_func: public Item_str_func
27 {
28 public:
29  Item_geometry_func() :Item_str_func() {}
30  Item_geometry_func(Item *a) :Item_str_func(a) {}
31  Item_geometry_func(Item *a,Item *b) :Item_str_func(a,b) {}
32  Item_geometry_func(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
33  Item_geometry_func(List<Item> &list) :Item_str_func(list) {}
34  void fix_length_and_dec();
35  enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
36  Field *tmp_table_field(TABLE *t_arg);
37  bool is_null() { (void) val_int(); return null_value; }
38 };
39 
40 class Item_func_geometry_from_text: public Item_geometry_func
41 {
42 public:
43  Item_func_geometry_from_text(Item *a) :Item_geometry_func(a) {}
44  Item_func_geometry_from_text(Item *a, Item *srid) :Item_geometry_func(a, srid) {}
45  const char *func_name() const { return "st_geometryfromtext"; }
46  String *val_str(String *);
47 };
48 
49 class Item_func_geometry_from_wkb: public Item_geometry_func
50 {
51  String tmp_value;
52 public:
53  Item_func_geometry_from_wkb(Item *a): Item_geometry_func(a) {}
54  Item_func_geometry_from_wkb(Item *a, Item *srid): Item_geometry_func(a, srid) {}
55  const char *func_name() const { return "st_geometryfromwkb"; }
56  String *val_str(String *);
57 };
58 
59 class Item_func_as_wkt: public Item_str_ascii_func
60 {
61 public:
62  Item_func_as_wkt(Item *a): Item_str_ascii_func(a) {}
63  const char *func_name() const { return "st_astext"; }
64  String *val_str_ascii(String *);
65  void fix_length_and_dec();
66 };
67 
68 class Item_func_as_wkb: public Item_geometry_func
69 {
70 public:
71  Item_func_as_wkb(Item *a): Item_geometry_func(a) {}
72  const char *func_name() const { return "st_aswkb"; }
73  String *val_str(String *);
74  enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
75 };
76 
77 class Item_func_geometry_type: public Item_str_ascii_func
78 {
79 public:
80  Item_func_geometry_type(Item *a): Item_str_ascii_func(a) {}
81  String *val_str_ascii(String *);
82  const char *func_name() const { return "st_geometrytype"; }
83  void fix_length_and_dec()
84  {
85  // "GeometryCollection" is the longest
86  fix_length_and_charset(20, default_charset());
87  maybe_null= 1;
88  };
89 };
90 
91 class Item_func_centroid: public Item_geometry_func
92 {
93 public:
94  Item_func_centroid(Item *a): Item_geometry_func(a) {}
95  const char *func_name() const { return "st_centroid"; }
96  String *val_str(String *);
97  Field::geometry_type get_geometry_type() const;
98 };
99 
100 class Item_func_envelope: public Item_geometry_func
101 {
102 public:
103  Item_func_envelope(Item *a): Item_geometry_func(a) {}
104  const char *func_name() const { return "st_envelope"; }
105  String *val_str(String *);
106  Field::geometry_type get_geometry_type() const;
107 };
108 
109 class Item_func_point: public Item_geometry_func
110 {
111 public:
112  Item_func_point(Item *a, Item *b): Item_geometry_func(a, b) {}
113  Item_func_point(Item *a, Item *b, Item *srid): Item_geometry_func(a, b, srid) {}
114  const char *func_name() const { return "st_point"; }
115  String *val_str(String *);
116  Field::geometry_type get_geometry_type() const;
117 };
118 
119 class Item_func_spatial_decomp: public Item_geometry_func
120 {
121  enum Functype decomp_func;
122 public:
123  Item_func_spatial_decomp(Item *a, Item_func::Functype ft) :
124  Item_geometry_func(a) { decomp_func = ft; }
125  const char *func_name() const
126  {
127  switch (decomp_func)
128  {
129  case SP_STARTPOINT:
130  return "st_startpoint";
131  case SP_ENDPOINT:
132  return "st_endpoint";
133  case SP_EXTERIORRING:
134  return "st_exteriorring";
135  default:
136  DBUG_ASSERT(0); // Should never happened
137  return "spatial_decomp_unknown";
138  }
139  }
140  String *val_str(String *);
141 };
142 
143 class Item_func_spatial_decomp_n: public Item_geometry_func
144 {
145  enum Functype decomp_func_n;
146 public:
147  Item_func_spatial_decomp_n(Item *a, Item *b, Item_func::Functype ft):
148  Item_geometry_func(a, b) { decomp_func_n = ft; }
149  const char *func_name() const
150  {
151  switch (decomp_func_n)
152  {
153  case SP_POINTN:
154  return "st_pointn";
155  case SP_GEOMETRYN:
156  return "st_geometryn";
157  case SP_INTERIORRINGN:
158  return "st_interiorringn";
159  default:
160  DBUG_ASSERT(0); // Should never happened
161  return "spatial_decomp_n_unknown";
162  }
163  }
164  String *val_str(String *);
165 };
166 
167 class Item_func_spatial_collection: public Item_geometry_func
168 {
169  String tmp_value;
170  enum Geometry::wkbType coll_type;
171  enum Geometry::wkbType item_type;
172 public:
173  Item_func_spatial_collection(
174  List<Item> &list, enum Geometry::wkbType ct, enum Geometry::wkbType it):
175  Item_geometry_func(list)
176  {
177  coll_type=ct;
178  item_type=it;
179  }
180  String *val_str(String *);
181  void fix_length_and_dec()
182  {
183  Item_geometry_func::fix_length_and_dec();
184  for (unsigned int i= 0; i < arg_count; ++i)
185  {
186  if (args[i]->fixed && args[i]->field_type() != MYSQL_TYPE_GEOMETRY)
187  {
188  String str;
189  args[i]->print(&str, QT_ORDINARY);
190  str.append('\0');
191  my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "non geometric",
192  str.ptr());
193  }
194  }
195  }
196 
197  const char *func_name() const { return "st_multipoint"; }
198 };
199 
200 
201 /*
202  Spatial relations
203 */
204 
205 class Item_func_spatial_mbr_rel: public Item_bool_func2
206 {
207  enum Functype spatial_rel;
208 public:
209  Item_func_spatial_mbr_rel(Item *a,Item *b, enum Functype sp_rel) :
210  Item_bool_func2(a,b) { spatial_rel = sp_rel; }
211  longlong val_int();
212  enum Functype functype() const
213  {
214  return spatial_rel;
215  }
216  enum Functype rev_functype() const
217  {
218  switch (spatial_rel)
219  {
220  case SP_CONTAINS_FUNC:
221  return SP_WITHIN_FUNC;
222  case SP_WITHIN_FUNC:
223  return SP_CONTAINS_FUNC;
224  default:
225  return spatial_rel;
226  }
227  }
228 
229  const char *func_name() const;
230  virtual inline void print(String *str, enum_query_type query_type)
231  {
232  Item_func::print(str, query_type);
233  }
234  void fix_length_and_dec() { maybe_null= 1; }
235  bool is_null() { (void) val_int(); return null_value; }
236 };
237 
238 
239 class Item_func_spatial_rel: public Item_bool_func2
240 {
241  enum Functype spatial_rel;
242  Gcalc_heap collector;
243  Gcalc_scan_iterator scan_it;
244  Gcalc_function func;
245  String tmp_value1,tmp_value2;
246 public:
247  Item_func_spatial_rel(Item *a,Item *b, enum Functype sp_rel);
248  virtual ~Item_func_spatial_rel();
249  longlong val_int();
250  enum Functype functype() const
251  {
252  return spatial_rel;
253  }
254  enum Functype rev_functype() const
255  {
256  switch (spatial_rel)
257  {
258  case SP_CONTAINS_FUNC:
259  return SP_WITHIN_FUNC;
260  case SP_WITHIN_FUNC:
261  return SP_CONTAINS_FUNC;
262  default:
263  return spatial_rel;
264  }
265  }
266 
267  const char *func_name() const;
268  virtual inline void print(String *str, enum_query_type query_type)
269  {
270  Item_func::print(str, query_type);
271  }
272 
273  void fix_length_and_dec() { maybe_null= 1; }
274  bool is_null() { (void) val_int(); return null_value; }
275 protected:
276  int func_touches();
277  int func_equals();
278 };
279 
280 
281 /*
282  Spatial operations
283 */
284 
285 class Item_func_spatial_operation: public Item_geometry_func
286 {
287 public:
288  Gcalc_function::op_type spatial_op;
289  Gcalc_heap collector;
290  Gcalc_function func;
291 
292  Gcalc_result_receiver res_receiver;
293  Gcalc_operation_reducer operation;
294  String tmp_value1,tmp_value2;
295 public:
296  Item_func_spatial_operation(Item *a,Item *b, Gcalc_function::op_type sp_op) :
297  Item_geometry_func(a, b), spatial_op(sp_op)
298  {}
299  virtual ~Item_func_spatial_operation();
300  String *val_str(String *);
301  const char *func_name() const;
302  virtual inline void print(String *str, enum_query_type query_type)
303  {
304  Item_func::print(str, query_type);
305  }
306 };
307 
308 
309 class Item_func_buffer: public Item_geometry_func
310 {
311 protected:
313  {
314  int m_npoints;
315  double m_d;
316  Gcalc_function::op_type m_buffer_op;
317  double x1,y1,x2,y2;
318  double x00,y00,x01,y01;
319  int add_edge_buffer(Gcalc_shape_status *st,
320  double x3, double y3, bool round_p1, bool round_p2);
321  int add_last_edge_buffer(Gcalc_shape_status *st);
322  int add_point_buffer(Gcalc_shape_status *st, double x, double y);
323  int complete(Gcalc_shape_status *st);
324  public:
325  Transporter(Gcalc_function *fn, Gcalc_heap *heap, double d) :
326  Gcalc_operation_transporter(fn, heap), m_npoints(0), m_d(d)
327  {
328  m_buffer_op= d > 0.0 ? Gcalc_function::op_union :
329  Gcalc_function::op_difference;
330  }
331  int single_point(Gcalc_shape_status *st, double x, double y);
332  int start_line(Gcalc_shape_status *st);
333  int complete_line(Gcalc_shape_status *st);
334  int start_poly(Gcalc_shape_status *st);
335  int complete_poly(Gcalc_shape_status *st);
336  int start_ring(Gcalc_shape_status *st);
337  int complete_ring(Gcalc_shape_status *st);
338  int add_point(Gcalc_shape_status *st, double x, double y);
339  int start_collection(Gcalc_shape_status *st, int nshapes);
340  int complete_collection(Gcalc_shape_status *st);
341  int collection_add_item(Gcalc_shape_status *st_collection,
342  Gcalc_shape_status *st_item);
343 
344  bool skip_point() const
345  { return m_buffer_op == Gcalc_function::op_difference; }
346  bool skip_line_string() const
347  { return m_buffer_op == Gcalc_function::op_difference; }
348  bool skip_poly() const
349  { return false; }
350  };
351  Gcalc_heap collector;
352  Gcalc_function func;
353 
354  Gcalc_result_receiver res_receiver;
355  Gcalc_operation_reducer operation;
356  String tmp_value;
357 
358 public:
359  Item_func_buffer(Item *obj, Item *distance):
360  Item_geometry_func(obj, distance) {}
361  const char *func_name() const { return "st_buffer"; }
362  String *val_str(String *);
363 };
364 
365 
366 class Item_func_isempty: public Item_bool_func
367 {
368 public:
369  Item_func_isempty(Item *a): Item_bool_func(a) {}
370  longlong val_int();
371  optimize_type select_optimize() const { return OPTIMIZE_NONE; }
372  const char *func_name() const { return "st_isempty"; }
373  void fix_length_and_dec() { maybe_null= 1; }
374 };
375 
376 class Item_func_issimple: public Item_bool_func
377 {
378  Gcalc_heap collector;
379  Gcalc_function func;
380  Gcalc_scan_iterator scan_it;
381  String tmp;
382 public:
383  Item_func_issimple(Item *a): Item_bool_func(a) {}
384  longlong val_int();
385  optimize_type select_optimize() const { return OPTIMIZE_NONE; }
386  const char *func_name() const { return "st_issimple"; }
387  void fix_length_and_dec() { maybe_null= 1; }
388 };
389 
390 class Item_func_isclosed: public Item_bool_func
391 {
392 public:
393  Item_func_isclosed(Item *a): Item_bool_func(a) {}
394  longlong val_int();
395  optimize_type select_optimize() const { return OPTIMIZE_NONE; }
396  const char *func_name() const { return "st_isclosed"; }
397  void fix_length_and_dec() { maybe_null= 1; }
398 };
399 
400 class Item_func_dimension: public Item_int_func
401 {
402  String value;
403 public:
404  Item_func_dimension(Item *a): Item_int_func(a) {}
405  longlong val_int();
406  const char *func_name() const { return "st_dimension"; }
407  void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
408 };
409 
410 class Item_func_x: public Item_real_func
411 {
412  String value;
413 public:
414  Item_func_x(Item *a): Item_real_func(a) {}
415  double val_real();
416  const char *func_name() const { return "st_x"; }
417  void fix_length_and_dec()
418  {
419  Item_real_func::fix_length_and_dec();
420  maybe_null= 1;
421  }
422 };
423 
424 
425 class Item_func_y: public Item_real_func
426 {
427  String value;
428 public:
429  Item_func_y(Item *a): Item_real_func(a) {}
430  double val_real();
431  const char *func_name() const { return "st_y"; }
432  void fix_length_and_dec()
433  {
434  Item_real_func::fix_length_and_dec();
435  maybe_null= 1;
436  }
437 };
438 
439 
440 class Item_func_numgeometries: public Item_int_func
441 {
442  String value;
443 public:
444  Item_func_numgeometries(Item *a): Item_int_func(a) {}
445  longlong val_int();
446  const char *func_name() const { return "st_numgeometries"; }
447  void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
448 };
449 
450 
451 class Item_func_numinteriorring: public Item_int_func
452 {
453  String value;
454 public:
455  Item_func_numinteriorring(Item *a): Item_int_func(a) {}
456  longlong val_int();
457  const char *func_name() const { return "st_numinteriorrings"; }
458  void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
459 };
460 
461 
462 class Item_func_numpoints: public Item_int_func
463 {
464  String value;
465 public:
466  Item_func_numpoints(Item *a): Item_int_func(a) {}
467  longlong val_int();
468  const char *func_name() const { return "st_numpoints"; }
469  void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
470 };
471 
472 
473 class Item_func_area: public Item_real_func
474 {
475  String value;
476 public:
477  Item_func_area(Item *a): Item_real_func(a) {}
478  double val_real();
479  const char *func_name() const { return "st_area"; }
480  void fix_length_and_dec()
481  {
482  Item_real_func::fix_length_and_dec();
483  maybe_null= 1;
484  }
485 };
486 
487 
488 class Item_func_glength: public Item_real_func
489 {
490  String value;
491 public:
492  Item_func_glength(Item *a): Item_real_func(a) {}
493  double val_real();
494  const char *func_name() const { return "st_length"; }
495  void fix_length_and_dec()
496  {
497  Item_real_func::fix_length_and_dec();
498  maybe_null= 1;
499  }
500 };
501 
502 
503 class Item_func_srid: public Item_int_func
504 {
505  String value;
506 public:
507  Item_func_srid(Item *a): Item_int_func(a) {}
508  longlong val_int();
509  const char *func_name() const { return "srid"; }
510  void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
511 };
512 
513 
514 class Item_func_distance: public Item_real_func
515 {
516  String tmp_value1;
517  String tmp_value2;
518  Gcalc_heap collector;
519  Gcalc_function func;
520  Gcalc_scan_iterator scan_it;
521 public:
522  Item_func_distance(Item *a, Item *b): Item_real_func(a, b) {}
523  double val_real();
524  const char *func_name() const { return "st_distance"; }
525 };
526 
527 
528 #ifndef DBUG_OFF
529 class Item_func_gis_debug: public Item_int_func
530 {
531 public:
532  Item_func_gis_debug(Item *a) :Item_int_func(a) { null_value= false; }
533  const char *func_name() const { return "st_gis_debug"; }
534  longlong val_int();
535 };
536 #endif
537 
538 
539 #define GEOM_NEW(thd, obj_constructor) new (thd->mem_root) obj_constructor
540 
541 #else /*HAVE_SPATIAL*/
542 
543 #define GEOM_NEW(thd, obj_constructor) NULL
544 
545 #endif /*HAVE_SPATIAL*/
546 #endif /*ITEM_GEOFUNC_INCLUDED*/
547