1 #ifndef ITEM_GEOFUNC_INCLUDED
2 #define ITEM_GEOFUNC_INCLUDED
3 
4 /* Copyright (c) 2000, 2016, 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
17    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA */
18 
19 
20 /* This file defines all spatial functions */
21 
22 #ifdef HAVE_SPATIAL
23 
24 #ifdef USE_PRAGMA_INTERFACE
25 #pragma interface			/* gcc class implementation */
26 #endif
27 
28 class Item_geometry_func: public Item_str_func
29 {
30 public:
Item_geometry_func()31   Item_geometry_func() :Item_str_func() {}
Item_geometry_func(Item * a)32   Item_geometry_func(Item *a) :Item_str_func(a) {}
Item_geometry_func(Item * a,Item * b)33   Item_geometry_func(Item *a,Item *b) :Item_str_func(a,b) {}
Item_geometry_func(Item * a,Item * b,Item * c)34   Item_geometry_func(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
Item_geometry_func(List<Item> & list)35   Item_geometry_func(List<Item> &list) :Item_str_func(list) {}
36   void fix_length_and_dec();
field_type()37   enum_field_types field_type() const  { return MYSQL_TYPE_GEOMETRY; }
38   Field *tmp_table_field(TABLE *t_arg);
is_null()39   bool is_null() { (void) val_int(); return null_value; }
40 };
41 
42 class Item_func_geometry_from_text: public Item_geometry_func
43 {
44 public:
Item_func_geometry_from_text(Item * a)45   Item_func_geometry_from_text(Item *a) :Item_geometry_func(a) {}
Item_func_geometry_from_text(Item * a,Item * srid)46   Item_func_geometry_from_text(Item *a, Item *srid) :Item_geometry_func(a, srid) {}
func_name()47   const char *func_name() const { return "geometryfromtext"; }
48   String *val_str(String *);
49 };
50 
51 class Item_func_geometry_from_wkb: public Item_geometry_func
52 {
53 public:
Item_func_geometry_from_wkb(Item * a)54   Item_func_geometry_from_wkb(Item *a): Item_geometry_func(a) {}
Item_func_geometry_from_wkb(Item * a,Item * srid)55   Item_func_geometry_from_wkb(Item *a, Item *srid): Item_geometry_func(a, srid) {}
func_name()56   const char *func_name() const { return "geometryfromwkb"; }
57   String *val_str(String *);
58 };
59 
60 class Item_func_as_wkt: public Item_str_ascii_func
61 {
62 public:
Item_func_as_wkt(Item * a)63   Item_func_as_wkt(Item *a): Item_str_ascii_func(a) {}
func_name()64   const char *func_name() const { return "astext"; }
65   String *val_str_ascii(String *);
66   void fix_length_and_dec();
67 };
68 
69 class Item_func_as_wkb: public Item_geometry_func
70 {
71 public:
Item_func_as_wkb(Item * a)72   Item_func_as_wkb(Item *a): Item_geometry_func(a) {}
func_name()73   const char *func_name() const { return "aswkb"; }
74   String *val_str(String *);
field_type()75   enum_field_types field_type() const  { return MYSQL_TYPE_BLOB; }
76 };
77 
78 class Item_func_geometry_type: public Item_str_ascii_func
79 {
80 public:
Item_func_geometry_type(Item * a)81   Item_func_geometry_type(Item *a): Item_str_ascii_func(a) {}
82   String *val_str_ascii(String *);
func_name()83   const char *func_name() const { return "geometrytype"; }
fix_length_and_dec()84   void fix_length_and_dec()
85   {
86     // "GeometryCollection" is the longest
87     fix_length_and_charset(20, default_charset());
88     maybe_null= 1;
89   };
90 };
91 
92 class Item_func_centroid: public Item_geometry_func
93 {
94 public:
Item_func_centroid(Item * a)95   Item_func_centroid(Item *a): Item_geometry_func(a) {}
func_name()96   const char *func_name() const { return "centroid"; }
97   String *val_str(String *);
98   Field::geometry_type get_geometry_type() const;
99 };
100 
101 class Item_func_envelope: public Item_geometry_func
102 {
103 public:
Item_func_envelope(Item * a)104   Item_func_envelope(Item *a): Item_geometry_func(a) {}
func_name()105   const char *func_name() const { return "envelope"; }
106   String *val_str(String *);
107   Field::geometry_type get_geometry_type() const;
108 };
109 
110 class Item_func_point: public Item_geometry_func
111 {
112 public:
Item_func_point(Item * a,Item * b)113   Item_func_point(Item *a, Item *b): Item_geometry_func(a, b) {}
Item_func_point(Item * a,Item * b,Item * srid)114   Item_func_point(Item *a, Item *b, Item *srid): Item_geometry_func(a, b, srid) {}
func_name()115   const char *func_name() const { return "point"; }
116   String *val_str(String *);
117   Field::geometry_type get_geometry_type() const;
118 };
119 
120 class Item_func_spatial_decomp: public Item_geometry_func
121 {
122   enum Functype decomp_func;
123 public:
Item_func_spatial_decomp(Item * a,Item_func::Functype ft)124   Item_func_spatial_decomp(Item *a, Item_func::Functype ft) :
125   	Item_geometry_func(a) { decomp_func = ft; }
func_name()126   const char *func_name() const
127   {
128     switch (decomp_func)
129     {
130       case SP_STARTPOINT:
131         return "startpoint";
132       case SP_ENDPOINT:
133         return "endpoint";
134       case SP_EXTERIORRING:
135         return "exteriorring";
136       default:
137 	DBUG_ASSERT(0);  // Should never happened
138         return "spatial_decomp_unknown";
139     }
140   }
141   String *val_str(String *);
142 };
143 
144 class Item_func_spatial_decomp_n: public Item_geometry_func
145 {
146   enum Functype decomp_func_n;
147 public:
Item_func_spatial_decomp_n(Item * a,Item * b,Item_func::Functype ft)148   Item_func_spatial_decomp_n(Item *a, Item *b, Item_func::Functype ft):
149   	Item_geometry_func(a, b) { decomp_func_n = ft; }
func_name()150   const char *func_name() const
151   {
152     switch (decomp_func_n)
153     {
154       case SP_POINTN:
155         return "pointn";
156       case SP_GEOMETRYN:
157         return "geometryn";
158       case SP_INTERIORRINGN:
159         return "interiorringn";
160       default:
161 	DBUG_ASSERT(0);  // Should never happened
162         return "spatial_decomp_n_unknown";
163     }
164   }
165   String *val_str(String *);
166 };
167 
168 class Item_func_spatial_collection: public Item_geometry_func
169 {
170   String tmp_value;
171   enum Geometry::wkbType coll_type;
172   enum Geometry::wkbType item_type;
173 public:
Item_func_spatial_collection(List<Item> & list,enum Geometry::wkbType ct,enum Geometry::wkbType it)174   Item_func_spatial_collection(
175      List<Item> &list, enum Geometry::wkbType ct, enum Geometry::wkbType it):
176   Item_geometry_func(list)
177   {
178     coll_type=ct;
179     item_type=it;
180   }
181   String *val_str(String *);
fix_length_and_dec()182   void fix_length_and_dec()
183   {
184     Item_geometry_func::fix_length_and_dec();
185     for (unsigned int i= 0; i < arg_count; ++i)
186     {
187       if (args[i]->fixed && args[i]->field_type() != MYSQL_TYPE_GEOMETRY)
188       {
189         String str;
190         args[i]->print(&str, QT_NO_DATA_EXPANSION);
191         str.append('\0');
192         my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "non geometric",
193                  str.ptr());
194       }
195     }
196   }
197 
func_name()198   const char *func_name() const { return "multipoint"; }
199 };
200 
201 /*
202   Spatial relations
203 */
204 
205 class Item_func_spatial_rel: public Item_bool_func2
206 {
207   enum Functype spatial_rel;
208 public:
Item_func_spatial_rel(Item * a,Item * b,enum Functype sp_rel)209   Item_func_spatial_rel(Item *a,Item *b, enum Functype sp_rel) :
210     Item_bool_func2(a,b) { spatial_rel = sp_rel; }
211   longlong val_int();
functype()212   enum Functype functype() const
213   {
214     switch (spatial_rel) {
215     case SP_CONTAINS_FUNC:
216       return SP_WITHIN_FUNC;
217     case SP_WITHIN_FUNC:
218       return SP_CONTAINS_FUNC;
219     default:
220       return spatial_rel;
221     }
222   }
rev_functype()223   enum Functype rev_functype() const { return spatial_rel; }
func_name()224   const char *func_name() const
225   {
226     switch (spatial_rel) {
227     case SP_CONTAINS_FUNC:
228       return "contains";
229     case SP_WITHIN_FUNC:
230       return "within";
231     case SP_EQUALS_FUNC:
232       return "equals";
233     case SP_DISJOINT_FUNC:
234       return "disjoint";
235     case SP_INTERSECTS_FUNC:
236       return "intersects";
237     case SP_TOUCHES_FUNC:
238       return "touches";
239     case SP_CROSSES_FUNC:
240       return "crosses";
241     case SP_OVERLAPS_FUNC:
242       return "overlaps";
243     default:
244       DBUG_ASSERT(0);  // Should never happened
245       return "sp_unknown";
246     }
247   }
248 
print(String * str,enum_query_type query_type)249   virtual inline void print(String *str, enum_query_type query_type)
250   {
251     Item_func::print(str, query_type);
252   }
253 
fix_length_and_dec()254   void fix_length_and_dec() { maybe_null= 1; }
is_null()255   bool is_null() { (void) val_int(); return null_value; }
256 };
257 
258 class Item_func_isempty: public Item_bool_func
259 {
260 public:
Item_func_isempty(Item * a)261   Item_func_isempty(Item *a): Item_bool_func(a) {}
262   longlong val_int();
select_optimize()263   optimize_type select_optimize() const { return OPTIMIZE_NONE; }
func_name()264   const char *func_name() const { return "isempty"; }
fix_length_and_dec()265   void fix_length_and_dec() { maybe_null= 1; }
266 };
267 
268 class Item_func_issimple: public Item_bool_func
269 {
270 public:
Item_func_issimple(Item * a)271   Item_func_issimple(Item *a): Item_bool_func(a) {}
272   longlong val_int();
select_optimize()273   optimize_type select_optimize() const { return OPTIMIZE_NONE; }
func_name()274   const char *func_name() const { return "issimple"; }
fix_length_and_dec()275   void fix_length_and_dec() { maybe_null= 1; }
276 };
277 
278 class Item_func_isclosed: public Item_bool_func
279 {
280 public:
Item_func_isclosed(Item * a)281   Item_func_isclosed(Item *a): Item_bool_func(a) {}
282   longlong val_int();
select_optimize()283   optimize_type select_optimize() const { return OPTIMIZE_NONE; }
func_name()284   const char *func_name() const { return "isclosed"; }
fix_length_and_dec()285   void fix_length_and_dec() { maybe_null= 1; }
286 };
287 
288 class Item_func_dimension: public Item_int_func
289 {
290   String value;
291 public:
Item_func_dimension(Item * a)292   Item_func_dimension(Item *a): Item_int_func(a) {}
293   longlong val_int();
func_name()294   const char *func_name() const { return "dimension"; }
fix_length_and_dec()295   void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
296 };
297 
298 class Item_func_x: public Item_real_func
299 {
300   String value;
301 public:
Item_func_x(Item * a)302   Item_func_x(Item *a): Item_real_func(a) {}
303   double val_real();
func_name()304   const char *func_name() const { return "x"; }
fix_length_and_dec()305   void fix_length_and_dec()
306   {
307     Item_real_func::fix_length_and_dec();
308     maybe_null= 1;
309   }
310 };
311 
312 
313 class Item_func_y: public Item_real_func
314 {
315   String value;
316 public:
Item_func_y(Item * a)317   Item_func_y(Item *a): Item_real_func(a) {}
318   double val_real();
func_name()319   const char *func_name() const { return "y"; }
fix_length_and_dec()320   void fix_length_and_dec()
321   {
322     Item_real_func::fix_length_and_dec();
323     maybe_null= 1;
324   }
325 };
326 
327 
328 class Item_func_numgeometries: public Item_int_func
329 {
330   String value;
331 public:
Item_func_numgeometries(Item * a)332   Item_func_numgeometries(Item *a): Item_int_func(a) {}
333   longlong val_int();
func_name()334   const char *func_name() const { return "numgeometries"; }
fix_length_and_dec()335   void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
336 };
337 
338 
339 class Item_func_numinteriorring: public Item_int_func
340 {
341   String value;
342 public:
Item_func_numinteriorring(Item * a)343   Item_func_numinteriorring(Item *a): Item_int_func(a) {}
344   longlong val_int();
func_name()345   const char *func_name() const { return "numinteriorrings"; }
fix_length_and_dec()346   void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
347 };
348 
349 
350 class Item_func_numpoints: public Item_int_func
351 {
352   String value;
353 public:
Item_func_numpoints(Item * a)354   Item_func_numpoints(Item *a): Item_int_func(a) {}
355   longlong val_int();
func_name()356   const char *func_name() const { return "numpoints"; }
fix_length_and_dec()357   void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
358 };
359 
360 
361 class Item_func_area: public Item_real_func
362 {
363   String value;
364 public:
Item_func_area(Item * a)365   Item_func_area(Item *a): Item_real_func(a) {}
366   double val_real();
func_name()367   const char *func_name() const { return "area"; }
fix_length_and_dec()368   void fix_length_and_dec()
369   {
370     Item_real_func::fix_length_and_dec();
371     maybe_null= 1;
372   }
373 };
374 
375 
376 class Item_func_glength: public Item_real_func
377 {
378   String value;
379 public:
Item_func_glength(Item * a)380   Item_func_glength(Item *a): Item_real_func(a) {}
381   double val_real();
func_name()382   const char *func_name() const { return "glength"; }
fix_length_and_dec()383   void fix_length_and_dec()
384   {
385     Item_real_func::fix_length_and_dec();
386     maybe_null= 1;
387   }
388 };
389 
390 
391 class Item_func_srid: public Item_int_func
392 {
393   String value;
394 public:
Item_func_srid(Item * a)395   Item_func_srid(Item *a): Item_int_func(a) {}
396   longlong val_int();
func_name()397   const char *func_name() const { return "srid"; }
fix_length_and_dec()398   void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
399 };
400 
401 #define GEOM_NEW(thd, obj_constructor) new (thd->mem_root) obj_constructor
402 
403 #else /*HAVE_SPATIAL*/
404 
405 #define GEOM_NEW(thd, obj_constructor) NULL
406 
407 #endif
408 
409 #endif /* ITEM_GEOFUNC_INCLUDED */
410