item_geofunc.h 39 KB
Newer Older
1 2 3
#ifndef ITEM_GEOFUNC_INCLUDED
#define ITEM_GEOFUNC_INCLUDED

4
/* Copyright (c) 2000, 2016 Oracle and/or its affiliates.
Marko Mäkelä's avatar
Marko Mäkelä committed
5
   Copyright (C) 2011, 2021, MariaDB
6 7 8

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
unknown's avatar
unknown committed
9
   the Free Software Foundation; version 2 of the License.
10 11 12 13 14 15 16 17

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
Vicențiu Ciorbaru's avatar
Vicențiu Ciorbaru committed
18
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1335  USA */
19 20 21 22


/* This file defines all spatial functions */

23
#include <bitset>
24 25
#include "sql_type_geom.h"
#include "item.h"
26 27
#include "gstream.h"
#include "spatial.h"
28
#include "gcalc_slicescan.h"
29
#include "gcalc_tools.h"
30

31
class Item_geometry_func: public Item_str_func
32 33
{
public:
34 35 36 37 38 39
  Item_geometry_func(THD *thd): Item_str_func(thd) {}
  Item_geometry_func(THD *thd, Item *a): Item_str_func(thd, a) {}
  Item_geometry_func(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {}
  Item_geometry_func(THD *thd, Item *a, Item *b, Item *c):
    Item_str_func(thd, a, b, c) {}
  Item_geometry_func(THD *thd, List<Item> &list): Item_str_func(thd, list) {}
40
  bool fix_length_and_dec(THD *thd) override;
41 42
  const Type_handler *type_handler() const override
  { return &type_handler_geometry; }
43 44
};

45 46 47 48 49 50 51 52

/*
  Functions returning REAL measurements of a single GEOMETRY argument
*/
class Item_real_func_args_geometry: public Item_real_func
{
protected:
  String value;
53
  bool check_arguments() const override
54 55
  {
    DBUG_ASSERT(arg_count == 1);
Monty's avatar
Monty committed
56
    return Type_handler_geometry::check_type_geom_or_binary(func_name_cstring(),
57
                                                            args[0]);
58 59 60 61 62 63 64 65 66 67 68 69
  }
public:
  Item_real_func_args_geometry(THD *thd, Item *a)
   :Item_real_func(thd, a) {}
};


/*
  Functions returning INT measurements of a single GEOMETRY argument
*/
class Item_long_func_args_geometry: public Item_long_func
{
70
  bool check_arguments() const override
71 72
  {
    DBUG_ASSERT(arg_count == 1);
Monty's avatar
Monty committed
73
    return Type_handler_geometry::check_type_geom_or_binary(func_name_cstring(),
74
                                                            args[0]);
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
  }
protected:
  String value;
public:
  Item_long_func_args_geometry(THD *thd, Item *a)
   :Item_long_func(thd, a) {}
};


/*
  Functions returning BOOL measurements of a single GEOMETRY argument
*/
class Item_bool_func_args_geometry: public Item_bool_func
{
protected:
  String value;
91
  bool check_arguments() const override
92 93
  {
    DBUG_ASSERT(arg_count == 1);
Monty's avatar
Monty committed
94
    return Type_handler_geometry::check_type_geom_or_binary(func_name_cstring(),
95
                                                            args[0]);
96 97 98 99 100 101 102 103 104 105 106 107 108
  }
public:
  Item_bool_func_args_geometry(THD *thd, Item *a)
   :Item_bool_func(thd, a) {}
};


/*
  Functions returning ASCII string measurements of a single GEOMETRY argument
*/
class Item_str_ascii_func_args_geometry: public Item_str_ascii_func
{
protected:
109
  bool check_arguments() const override
110 111
  {
    DBUG_ASSERT(arg_count >= 1);
Monty's avatar
Monty committed
112
    return Type_handler_geometry::check_type_geom_or_binary(func_name_cstring(),
113
                                                            args[0]);
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
  }
public:
  Item_str_ascii_func_args_geometry(THD *thd, Item *a)
   :Item_str_ascii_func(thd, a) {}
  Item_str_ascii_func_args_geometry(THD *thd, Item *a, Item *b)
   :Item_str_ascii_func(thd, a, b) {}
  Item_str_ascii_func_args_geometry(THD *thd, Item *a, Item *b, Item *c)
   :Item_str_ascii_func(thd, a, b, c) {}
};


/*
  Functions returning binary string measurements of a single GEOMETRY argument
*/
class Item_binary_func_args_geometry: public Item_str_func
{
protected:
131
  bool check_arguments() const override
132 133
  {
    DBUG_ASSERT(arg_count >= 1);
Monty's avatar
Monty committed
134
    return Type_handler_geometry::check_type_geom_or_binary(func_name_cstring(),
135
                                                            args[0]);
136 137 138 139 140 141 142 143 144 145 146 147 148
  }
public:
  Item_binary_func_args_geometry(THD *thd, Item *a)
   :Item_str_func(thd, a) {}
};


/*
  Functions returning GEOMETRY measurements of a single GEOEMETRY argument
*/
class Item_geometry_func_args_geometry: public Item_geometry_func
{
protected:
149
  bool check_arguments() const override
150 151
  {
    DBUG_ASSERT(arg_count >= 1);
Monty's avatar
Monty committed
152
    return Type_handler_geometry::check_type_geom_or_binary(func_name_cstring(),
153
                                                            args[0]);
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
  }
public:
  Item_geometry_func_args_geometry(THD *thd, Item *a)
   :Item_geometry_func(thd, a) {}
  Item_geometry_func_args_geometry(THD *thd, Item *a, Item *b)
   :Item_geometry_func(thd, a, b) {}
};


/*
  Functions returning REAL result relationships between two GEOMETRY arguments
*/
class Item_real_func_args_geometry_geometry: public Item_real_func
{
protected:
169
  bool check_arguments() const override
170 171
  {
    DBUG_ASSERT(arg_count >= 2);
Monty's avatar
Monty committed
172
    return Type_handler_geometry::check_types_geom_or_binary(func_name_cstring(),
173
                                                             args, 0, 2);
174 175 176 177 178 179 180 181 182 183 184 185 186 187
  }
public:
  Item_real_func_args_geometry_geometry(THD *thd, Item *a, Item *b)
   :Item_real_func(thd, a, b) {}
};


/*
  Functions returning BOOL result relationships between two GEOMETRY arguments
*/
class Item_bool_func_args_geometry_geometry: public Item_bool_func
{
protected:
  String value;
188
  bool check_arguments() const override
189 190
  {
    DBUG_ASSERT(arg_count >= 2);
Monty's avatar
Monty committed
191
    return Type_handler_geometry::check_types_geom_or_binary(func_name_cstring(),
192
                                                             args, 0, 2);
193 194 195 196 197 198 199
  }
public:
  Item_bool_func_args_geometry_geometry(THD *thd, Item *a, Item *b, Item *c)
   :Item_bool_func(thd, a, b, c) {}
};


200 201
class Item_func_geometry_from_text: public Item_geometry_func
{
202
  bool check_arguments() const override
203
  {
Monty's avatar
Monty committed
204
    return args[0]->check_type_general_purpose_string(func_name_cstring()) ||
205 206
           check_argument_types_can_return_int(1, MY_MIN(2, arg_count));
  }
207
public:
208 209 210
  Item_func_geometry_from_text(THD *thd, Item *a): Item_geometry_func(thd, a) {}
  Item_func_geometry_from_text(THD *thd, Item *a, Item *srid):
    Item_geometry_func(thd, a, srid) {}
Monty's avatar
Monty committed
211 212 213 214 215
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_geometryfromtext") };
    return name;
  }
216
  String *val_str(String *) override;
217
  Item *do_get_copy(THD *thd) const override
218
  { return get_item_copy<Item_func_geometry_from_text>(thd, this); }
219 220
};

221
class Item_func_geometry_from_wkb: public Item_geometry_func
222
{
223
  bool check_arguments() const override
224
  {
225
    return
Monty's avatar
Monty committed
226
      Type_handler_geometry::check_type_geom_or_binary(func_name_cstring(), args[0]) ||
227
      check_argument_types_can_return_int(1, MY_MIN(2, arg_count));
228
  }
229
public:
230 231 232
  Item_func_geometry_from_wkb(THD *thd, Item *a): Item_geometry_func(thd, a) {}
  Item_func_geometry_from_wkb(THD *thd, Item *a, Item *srid):
    Item_geometry_func(thd, a, srid) {}
Monty's avatar
Monty committed
233 234 235 236 237
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_geometryfromwkb") };
    return name;
  }
238
  String *val_str(String *) override;
239
  Item *do_get_copy(THD *thd) const override
240
  { return get_item_copy<Item_func_geometry_from_wkb>(thd, this); }
241 242
};

243 244 245 246

class Item_func_geometry_from_json: public Item_geometry_func
{
  String tmp_js;
247
  bool check_arguments() const override
248 249
  {
    // TODO: check with Alexey, for better args[1] and args[2] type control
Monty's avatar
Monty committed
250
    return args[0]->check_type_general_purpose_string(func_name_cstring()) ||
251 252
           check_argument_types_traditional_scalar(1, MY_MIN(3, arg_count));
  }
253 254 255 256 257 258
public:
  Item_func_geometry_from_json(THD *thd, Item *js): Item_geometry_func(thd, js) {}
  Item_func_geometry_from_json(THD *thd, Item *js, Item *opt):
    Item_geometry_func(thd, js, opt) {}
  Item_func_geometry_from_json(THD *thd, Item *js, Item *opt, Item *srid):
    Item_geometry_func(thd, js, opt, srid) {}
Monty's avatar
Monty committed
259 260 261 262 263
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_geomfromgeojson") };
    return name;
  }
264
  String *val_str(String *) override;
265
  Item *do_get_copy(THD *thd) const override
266
  { return get_item_copy<Item_func_geometry_from_json>(thd, this); }
267 268 269
};


270
class Item_func_as_wkt: public Item_str_ascii_func_args_geometry
271 272
{
public:
273 274
  Item_func_as_wkt(THD *thd, Item *a)
   :Item_str_ascii_func_args_geometry(thd, a) {}
Monty's avatar
Monty committed
275 276 277 278 279
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_astext") };
    return name;
  }
280
  String *val_str_ascii(String *) override;
281
  bool fix_length_and_dec(THD *thd) override;
282
  Item *do_get_copy(THD *thd) const override
283
  { return get_item_copy<Item_func_as_wkt>(thd, this); }
284 285
};

286
class Item_func_as_wkb: public Item_binary_func_args_geometry
287 288
{
public:
289 290
  Item_func_as_wkb(THD *thd, Item *a)
   :Item_binary_func_args_geometry(thd, a) {}
Monty's avatar
Monty committed
291 292 293 294 295
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_aswkb") };
    return name;
  }
296 297 298
  String *val_str(String *) override;
  const Type_handler *type_handler() const override
  { return &type_handler_long_blob; }
299
  bool fix_length_and_dec(THD *thd) override
300 301 302 303
  {
    collation.set(&my_charset_bin);
    decimals=0;
    max_length= (uint32) UINT_MAX32;
304
    set_maybe_null();
305
    return FALSE;
306
  }
307
  Item *do_get_copy(THD *thd) const override
308
  { return get_item_copy<Item_func_as_wkb>(thd, this); }
309 310
};

311

312
class Item_func_as_geojson: public Item_str_ascii_func_args_geometry
313
{
314
  bool check_arguments() const override
315 316 317 318 319
  {
    // TODO: check with Alexey, for better args[1] and args[2] type control
    return Item_str_ascii_func_args_geometry::check_arguments() ||
           check_argument_types_traditional_scalar(1, MY_MIN(3, arg_count));
  }
320
public:
321 322 323 324 325 326
  Item_func_as_geojson(THD *thd, Item *js)
   :Item_str_ascii_func_args_geometry(thd, js) {}
  Item_func_as_geojson(THD *thd, Item *js, Item *max_dec_digits)
   :Item_str_ascii_func_args_geometry(thd, js, max_dec_digits) {}
  Item_func_as_geojson(THD *thd, Item *js, Item *max_dec_digits, Item *opt)
   :Item_str_ascii_func_args_geometry(thd, js, max_dec_digits, opt) {}
Monty's avatar
Monty committed
327 328 329 330 331
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_asgeojson") };
    return name;
  }
332
  bool fix_length_and_dec(THD *thd) override;
333
  String *val_str_ascii(String *) override;
334
  Item *do_get_copy(THD *thd) const override
335
  { return get_item_copy<Item_func_as_geojson>(thd, this); }
336 337 338
};


339
class Item_func_geometry_type: public Item_str_ascii_func_args_geometry
340 341
{
public:
342 343
  Item_func_geometry_type(THD *thd, Item *a)
   :Item_str_ascii_func_args_geometry(thd, a) {}
344
  String *val_str_ascii(String *) override;
Monty's avatar
Monty committed
345 346 347 348 349
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_geometrytype") };
    return name;
  }
350
  bool fix_length_and_dec(THD *thd) override
351
  {
352 353
    // "GeometryCollection" is the longest
    fix_length_and_charset(20, default_charset());
354
    set_maybe_null();
355
    return FALSE;
356
  };
357
  Item *do_get_copy(THD *thd) const override
358
  { return get_item_copy<Item_func_geometry_type>(thd, this); }
359 360
};

361 362

// #define HEAVY_CONVEX_HULL
363
class Item_func_convexhull: public Item_geometry_func_args_geometry
364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
{
  class ch_node: public Gcalc_dyn_list::Item
  {
  public:
    const Gcalc_heap::Info *pi;
    ch_node *prev;
    Gcalc_dyn_list::Item *next;
    ch_node *get_next() { return (ch_node *) next; }
  };

  Gcalc_heap collector;
  Gcalc_function func;
  Gcalc_dyn_list res_heap;

  Gcalc_result_receiver res_receiver;
  String tmp_value;
#ifdef HEAVY_CONVEX_HULL
  Gcalc_scan_iterator scan_it;
#endif /*HEAVY_CONVEX_HULL*/
  ch_node *new_ch_node() { return (ch_node *) res_heap.new_item(); }
  int add_node_to_line(ch_node **p_cur, int dir, const Gcalc_heap::Info *pi);
public:
386 387
  Item_func_convexhull(THD *thd, Item *a)
   :Item_geometry_func_args_geometry(thd, a),
388 389
    res_heap(8192, sizeof(ch_node))
    {}
Monty's avatar
Monty committed
390 391 392 393 394
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_convexhull") };
    return name;
  }
395
  String *val_str(String *) override;
396
  Item *do_get_copy(THD *thd) const override
397
  { return get_item_copy<Item_func_convexhull>(thd, this); }
398 399 400
};


401
class Item_func_centroid: public Item_geometry_func_args_geometry
402 403
{
public:
404 405
  Item_func_centroid(THD *thd, Item *a)
   :Item_geometry_func_args_geometry(thd, a) {}
Monty's avatar
Monty committed
406 407 408 409 410
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_centroid") };
    return name;
  }
411 412
  String *val_str(String *) override;
  const Type_handler *type_handler() const override
413 414 415
  {
    return &type_handler_point;
  }
416
  Item *do_get_copy(THD *thd) const override
417
  { return get_item_copy<Item_func_centroid>(thd, this); }
418 419
};

420
class Item_func_envelope: public Item_geometry_func_args_geometry
421 422
{
public:
423 424
  Item_func_envelope(THD *thd, Item *a)
   :Item_geometry_func_args_geometry(thd, a) {}
Monty's avatar
Monty committed
425 426 427 428 429
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_envelope") };
    return name;
  }
430 431
  String *val_str(String *) override;
  const Type_handler *type_handler() const override
432 433 434
  {
    return &type_handler_polygon;
  }
435
  Item *do_get_copy(THD *thd) const override
436
  { return get_item_copy<Item_func_envelope>(thd, this); }
437 438
};

439

440
class Item_func_boundary: public Item_geometry_func_args_geometry
441 442 443 444 445 446 447 448 449 450 451
{
  class Transporter : public Gcalc_shape_transporter
  {
    Gcalc_result_receiver *m_receiver;
    uint n_points;
    Gcalc_function::shape_type current_type;
    double last_x, last_y;
  public:
    Transporter(Gcalc_result_receiver *receiver) :
      Gcalc_shape_transporter(NULL), m_receiver(receiver)
    {}
452 453 454 455 456 457 458 459 460 461
    int single_point(double x, double y) override;
    int start_line() override;
    int complete_line() override;
    int start_poly() override;
    int complete_poly() override;
    int start_ring() override;
    int complete_ring() override;
    int add_point(double x, double y) override;

    int start_collection(int n_objects) override;
462 463 464
  };
  Gcalc_result_receiver res_receiver;
public:
465 466
  Item_func_boundary(THD *thd, Item *a)
   :Item_geometry_func_args_geometry(thd, a) {}
Monty's avatar
Monty committed
467 468 469 470 471
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_boundary") };
    return name;
  }
472
  String *val_str(String *) override;
473
  Item *do_get_copy(THD *thd) const override
474
  { return get_item_copy<Item_func_boundary>(thd, this); }
475 476 477
};


478
class Item_func_point: public Item_geometry_func
479
{
480
  bool check_arguments() const override
481
  { return check_argument_types_can_return_real(0, 2); }
482
public:
483 484 485
  Item_func_point(THD *thd, Item *a, Item *b): Item_geometry_func(thd, a, b) {}
  Item_func_point(THD *thd, Item *a, Item *b, Item *srid):
    Item_geometry_func(thd, a, b, srid) {}
Monty's avatar
Monty committed
486 487 488 489 490
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("point") };
    return name;
  }
491 492
  String *val_str(String *) override;
  const Type_handler *type_handler() const override
493 494 495
  {
    return &type_handler_point;
  }
496
  Item *do_get_copy(THD *thd) const override
497
  { return get_item_copy<Item_func_point>(thd, this); }
498 499
};

500
class Item_func_spatial_decomp: public Item_geometry_func_args_geometry
501 502 503
{
  enum Functype decomp_func;
public:
504
  Item_func_spatial_decomp(THD *thd, Item *a, Item_func::Functype ft):
505
    Item_geometry_func_args_geometry(thd, a) { decomp_func = ft; }
Monty's avatar
Monty committed
506
  LEX_CSTRING func_name_cstring() const override
507
  { 
Monty's avatar
Monty committed
508 509 510 511 512
    static LEX_CSTRING startpoint= {STRING_WITH_LEN("st_startpoint") };
    static LEX_CSTRING endpoint= {STRING_WITH_LEN("st_endpoint") };
    static LEX_CSTRING exteriorring= {STRING_WITH_LEN("st_exteriorring") };
    static LEX_CSTRING unknown= {STRING_WITH_LEN("spatial_decomp_unknown") };
    switch (decomp_func) {
513
      case SP_STARTPOINT:
Monty's avatar
Monty committed
514
        return startpoint;
515
      case SP_ENDPOINT:
Monty's avatar
Monty committed
516
        return endpoint;
517
      case SP_EXTERIORRING:
Monty's avatar
Monty committed
518
        return exteriorring;
519
      default:
520
	DBUG_ASSERT(0);  // Should never happened
Monty's avatar
Monty committed
521
        return unknown;
522 523
    }
  }
524
  String *val_str(String *) override;
525
  Item *do_get_copy(THD *thd) const override
526
  { return get_item_copy<Item_func_spatial_decomp>(thd, this); }
527 528
};

529
class Item_func_spatial_decomp_n: public Item_geometry_func_args_geometry
530 531
{
  enum Functype decomp_func_n;
532
  bool check_arguments() const override
533 534
  {
    return Item_geometry_func_args_geometry::check_arguments() ||
Monty's avatar
Monty committed
535
           args[1]->check_type_can_return_int(func_name_cstring());
536
  }
537
public:
538 539 540 541
  Item_func_spatial_decomp_n(THD *thd, Item *a, Item *b, Item_func::Functype ft)
   :Item_geometry_func_args_geometry(thd, a, b),
    decomp_func_n(ft)
  { }
Monty's avatar
Monty committed
542
  LEX_CSTRING func_name_cstring() const override
543
  { 
Monty's avatar
Monty committed
544 545 546 547 548 549
    static LEX_CSTRING pointn= {STRING_WITH_LEN("st_pointn") };
    static LEX_CSTRING geometryn= {STRING_WITH_LEN("st_geometryn") };
    static LEX_CSTRING interiorringn= {STRING_WITH_LEN("st_interiorringn") };
    static LEX_CSTRING unknown= {STRING_WITH_LEN("spatial_decomp_unknown") };

    switch (decomp_func_n) {
550
      case SP_POINTN:
Monty's avatar
Monty committed
551
        return pointn;
552
      case SP_GEOMETRYN:
Monty's avatar
Monty committed
553
        return geometryn;
554
      case SP_INTERIORRINGN:
Monty's avatar
Monty committed
555
        return interiorringn;
556
      default:
557
	DBUG_ASSERT(0);  // Should never happened
Monty's avatar
Monty committed
558
        return unknown;
559 560
    }
  }
561
  String *val_str(String *) override;
562
  Item *do_get_copy(THD *thd) const override
563
  { return get_item_copy<Item_func_spatial_decomp_n>(thd, this); }
564 565
};

566
class Item_func_spatial_collection: public Item_geometry_func
567
{
568
  bool check_arguments() const override
569
  {
Monty's avatar
Monty committed
570
    return Type_handler_geometry::check_types_geom_or_binary(func_name_cstring(), args,
571
                                                             0, arg_count);
572
  }
573 574 575
  enum Geometry::wkbType coll_type; 
  enum Geometry::wkbType item_type;
public:
576
  Item_func_spatial_collection(THD *thd,
577
     List<Item> &list, enum Geometry::wkbType ct, enum Geometry::wkbType it):
578
  Item_geometry_func(thd, list)
579 580 581 582
  {
    coll_type=ct;
    item_type=it;
  }
583
  String *val_str(String *) override;
584
  bool fix_length_and_dec(THD *thd) override
585
  {
586
    if (Item_geometry_func::fix_length_and_dec(thd))
587
      return TRUE;
588
    for (unsigned int i= 0; i < arg_count; ++i)
589
    {
590
      if (args[i]->fixed() && args[i]->field_type() != MYSQL_TYPE_GEOMETRY)
591 592
      {
        String str;
593
        args[i]->print(&str, QT_NO_DATA_EXPANSION);
594 595 596
        str.append('\0');
        my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "non geometric",
                 str.ptr());
597
        return TRUE;
598 599
      }
    }
600
    return FALSE;
601
  }
602 603 604 605 606 607 608 609 610 611 612
};


class Item_func_geometrycollection: public Item_func_spatial_collection
{
public:
  Item_func_geometrycollection(THD *thd, List<Item> &list)
   :Item_func_spatial_collection(thd, list,
                                 Geometry::wkb_geometrycollection,
                                 Geometry::wkb_point)
  { }
613
  const Type_handler *type_handler() const override
614 615 616
  {
    return &type_handler_geometrycollection;
  }
Monty's avatar
Monty committed
617 618 619 620 621
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("geometrycollection") };
    return name;
  }
622
  Item *do_get_copy(THD *thd) const override
623
  { return get_item_copy<Item_func_geometrycollection>(thd, this); }
624 625
};

626

627 628 629 630 631 632 633 634
class Item_func_linestring: public Item_func_spatial_collection
{
public:
  Item_func_linestring(THD *thd, List<Item> &list)
   :Item_func_spatial_collection(thd, list,
                                 Geometry::wkb_linestring,
                                 Geometry::wkb_point)
  { }
635 636
  const Type_handler *type_handler() const override
  { return &type_handler_linestring; }
Monty's avatar
Monty committed
637 638 639 640 641
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("linestring") };
    return name;
  }
642
  Item *do_get_copy(THD *thd) const override
643 644 645 646 647 648 649 650 651 652 653 654
  { return get_item_copy<Item_func_linestring>(thd, this); }
};


class Item_func_polygon: public Item_func_spatial_collection
{
public:
  Item_func_polygon(THD *thd, List<Item> &list)
   :Item_func_spatial_collection(thd, list,
                                 Geometry::wkb_polygon,
                                 Geometry::wkb_linestring)
  { }
655 656
  const Type_handler *type_handler() const override
  { return &type_handler_polygon; }
Monty's avatar
Monty committed
657 658 659 660 661
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("polygon") };
    return name;
  }
662
  Item *do_get_copy(THD *thd) const override
663 664 665 666 667 668 669 670 671 672 673 674
  { return get_item_copy<Item_func_polygon>(thd, this); }
};


class Item_func_multilinestring: public Item_func_spatial_collection
{
public:
  Item_func_multilinestring(THD *thd, List<Item> &list)
   :Item_func_spatial_collection(thd, list,
                                 Geometry::wkb_multilinestring,
                                 Geometry::wkb_linestring)
  { }
675
  const Type_handler *type_handler() const override
676 677 678
  {
    return &type_handler_multilinestring;
  }
Monty's avatar
Monty committed
679 680 681 682 683
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("multilinestring") };
    return name;
  }
684
  Item *do_get_copy(THD *thd) const override
685 686 687 688 689 690 691 692 693 694 695 696
  { return get_item_copy<Item_func_multilinestring>(thd, this); }
};


class Item_func_multipoint: public Item_func_spatial_collection
{
public:
  Item_func_multipoint(THD *thd, List<Item> &list)
   :Item_func_spatial_collection(thd, list,
                                 Geometry::wkb_multipoint,
                                 Geometry::wkb_point)
  { }
697
  const Type_handler *type_handler() const override
698 699 700
  {
    return &type_handler_multipoint;
  }
Monty's avatar
Monty committed
701 702 703 704 705
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("multipoint") };
    return name;
  }
706
  Item *do_get_copy(THD *thd) const override
707 708 709 710 711 712 713 714 715 716 717 718
  { return get_item_copy<Item_func_multipoint>(thd, this); }
};


class Item_func_multipolygon: public Item_func_spatial_collection
{
public:
  Item_func_multipolygon(THD *thd, List<Item> &list)
   :Item_func_spatial_collection(thd, list,
                                 Geometry::wkb_multipolygon,
                                 Geometry::wkb_polygon)
  { }
719
  const Type_handler *type_handler() const override
720 721 722
  {
    return &type_handler_multipolygon;
  }
Monty's avatar
Monty committed
723 724 725 726 727
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("multipolygon") };
    return name;
  }
728
  Item *do_get_copy(THD *thd) const override
729 730 731 732 733
  { return get_item_copy<Item_func_multipolygon>(thd, this); }
};



734 735 736 737
/*
  Spatial relations
*/

738
class Item_func_spatial_rel: public Item_bool_func2_with_rev
739
{
740
protected:
741
  enum Functype spatial_rel;
742
  String tmp_value1, tmp_value2;
743 744
  SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param, Field *field,
                       KEY_PART *key_part,
745 746
                       Item_func::Functype type, Item *value) override;
  bool check_arguments() const override
747 748
  {
    DBUG_ASSERT(arg_count >= 2);
Monty's avatar
Monty committed
749
    return Type_handler_geometry::check_types_geom_or_binary(func_name_cstring(),
750
                                                             args, 0, 2);
751
  }
752
public:
753
  Item_func_spatial_rel(THD *thd, Item *a, Item *b, enum Functype sp_rel):
754
    Item_bool_func2_with_rev(thd, a, b), spatial_rel(sp_rel)
755
  {
756
    set_maybe_null();
757
  }
758 759
  enum Functype functype() const override { return spatial_rel; }
  enum Functype rev_functype() const override
760 761 762 763 764 765 766 767 768 769 770
  {
    switch (spatial_rel)
    {
      case SP_CONTAINS_FUNC:
        return SP_WITHIN_FUNC;
      case SP_WITHIN_FUNC:
        return SP_CONTAINS_FUNC;
      default:
        return spatial_rel;
    }
  }
771
  bool is_null() override { (void) val_int(); return null_value; }
772 773
  void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
                      uint *and_level, table_map usable_tables,
774
                      SARGABLE_PARAM **sargables) override
775 776 777 778
  {
    return add_key_fields_optimize_op(join, key_fields, and_level,
                                      usable_tables, sargables, false);
  }
779
  bool need_parentheses_in_default() override { return false; }
780
  Item *do_build_clone(THD *thd) const override { return nullptr; }
781 782
};

783

784 785 786
class Item_func_spatial_mbr_rel: public Item_func_spatial_rel
{
public:
787 788
  Item_func_spatial_mbr_rel(THD *thd, Item *a, Item *b, enum Functype sp_rel):
    Item_func_spatial_rel(thd, a, b, sp_rel)
789
  { }
790
  longlong val_int() override;
Monty's avatar
Monty committed
791
  LEX_CSTRING func_name_cstring() const override;
792
  Item *do_get_copy(THD *thd) const override
793
  { return get_item_copy<Item_func_spatial_mbr_rel>(thd, this); }
794 795 796 797
};


class Item_func_spatial_precise_rel: public Item_func_spatial_rel
798 799 800 801 802
{
  Gcalc_heap collector;
  Gcalc_scan_iterator scan_it;
  Gcalc_function func;
public:
803 804
  Item_func_spatial_precise_rel(THD *thd, Item *a, Item *b, enum Functype sp_rel):
    Item_func_spatial_rel(thd, a, b, sp_rel), collector()
805
  { }
806
  longlong val_int() override;
Monty's avatar
Monty committed
807
  LEX_CSTRING func_name_cstring() const override;
808
  Item *do_get_copy(THD *thd) const override
809
  { return get_item_copy<Item_func_spatial_precise_rel>(thd, this); }
810 811
};

812

813
class Item_func_spatial_relate: public Item_bool_func_args_geometry_geometry
814 815 816 817 818
{
  Gcalc_heap collector;
  Gcalc_scan_iterator scan_it;
  Gcalc_function func;
  String tmp_value1, tmp_value2, tmp_matrix;
819
  bool check_arguments() const override
820 821
  {
    return Item_bool_func_args_geometry_geometry::check_arguments() ||
Monty's avatar
Monty committed
822
           args[2]->check_type_general_purpose_string(func_name_cstring());
823
  }
824
public:
825
  Item_func_spatial_relate(THD *thd, Item *a, Item *b, Item *matrix):
826
    Item_bool_func_args_geometry_geometry(thd, a, b, matrix)
827
  { }
828
  longlong val_int() override;
Monty's avatar
Monty committed
829 830 831 832 833
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_relate") };
    return name;
  }
834
  bool need_parentheses_in_default() override { return false; }
835
  Item *do_get_copy(THD *thd) const override
836
  { return get_item_copy<Item_func_spatial_relate>(thd, this); }
837 838 839
};


840 841 842 843
/*
  Spatial operations
*/

844
class Item_func_spatial_operation final: public Item_geometry_func
845
{
846
  bool check_arguments() const override
847 848
  {
    DBUG_ASSERT(arg_count >= 2);
Monty's avatar
Monty committed
849
    return Type_handler_geometry::check_types_geom_or_binary(func_name_cstring(),
850
                                                             args, 0, 2);
851
  }
852 853 854 855 856 857 858 859 860
public:
  Gcalc_function::op_type spatial_op;
  Gcalc_heap collector;
  Gcalc_function func;

  Gcalc_result_receiver res_receiver;
  Gcalc_operation_reducer operation;
  String tmp_value1,tmp_value2;
public:
861 862 863
  Item_func_spatial_operation(THD *thd, Item *a,Item *b,
                              Gcalc_function::op_type sp_op):
    Item_geometry_func(thd, a, b), spatial_op(sp_op)
864 865
  {}
  virtual ~Item_func_spatial_operation();
866
  String *val_str(String *) override;
Monty's avatar
Monty committed
867
  LEX_CSTRING func_name_cstring() const override;
868
  void print(String *str, enum_query_type query_type) override
869 870 871
  {
    Item_func::print(str, query_type);
  }
872
  Item *do_get_copy(THD *thd) const override
873
  { return get_item_copy<Item_func_spatial_operation>(thd, this); }
874 875 876
};


877
class Item_func_buffer final : public Item_geometry_func_args_geometry
878
{
879
  bool check_arguments() const override
880 881
  {
    return Item_geometry_func_args_geometry::check_arguments() ||
Monty's avatar
Monty committed
882
           args[1]->check_type_can_return_real(func_name_cstring());
883
  }
884 885 886 887 888 889 890 891 892 893 894 895
protected:
  class Transporter : public Gcalc_operation_transporter
  {
    int m_npoints;
    double m_d;
    double x1,y1,x2,y2;
    double x00,y00,x01,y01;
    int add_edge_buffer(double x3, double y3, bool round_p1, bool round_p2);
    int add_last_edge_buffer();
    int add_point_buffer(double x, double y);
    int complete();
    int m_nshapes;
896 897 898 899 900
    Gcalc_function::op_type buffer_op;
    int last_shape_pos;
    bool skip_line;

  public:
901
    Transporter(Gcalc_function *fn, Gcalc_heap *heap, double d) :
902 903 904 905
      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)
906
    {}
907 908 909 910 911 912 913 914 915 916
    int single_point(double x, double y) override;
    int start_line() override;
    int complete_line() override;
    int start_poly() override;
    int complete_poly() override;
    int start_ring() override;
    int complete_ring() override;
    int add_point(double x, double y) override;

    int start_collection(int n_objects) override;
917 918 919 920 921 922 923 924
  };
  Gcalc_heap collector;
  Gcalc_function func;

  Gcalc_result_receiver res_receiver;
  Gcalc_operation_reducer operation;

public:
925 926
  Item_func_buffer(THD *thd, Item *obj, Item *distance)
   :Item_geometry_func_args_geometry(thd, obj, distance) {}
Monty's avatar
Monty committed
927 928 929 930 931
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_buffer") };
    return name;
  }
932
  String *val_str(String *) override;
933
  Item *do_get_copy(THD *thd) const override
934
  { return get_item_copy<Item_func_buffer>(thd, this); }
935 936 937
};


938
class Item_func_isempty: public Item_bool_func_args_geometry
939 940
{
public:
941 942
  Item_func_isempty(THD *thd, Item *a)
   :Item_bool_func_args_geometry(thd, a) {}
943
  longlong val_int() override;
Monty's avatar
Monty committed
944 945 946 947 948
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_isempty") };
    return name;
  }
949
  bool fix_length_and_dec(THD *thd) override
950 951
  { set_maybe_null(); return FALSE; }
  bool need_parentheses_in_default() override { return false; }
952
  Item *do_get_copy(THD *thd) const override
953
  { return get_item_copy<Item_func_isempty>(thd, this); }
954 955
};

956
class Item_func_issimple: public Item_long_func_args_geometry
957
{
958 959 960 961
  Gcalc_heap collector;
  Gcalc_function func;
  Gcalc_scan_iterator scan_it;
  String tmp;
962
public:
963 964
  Item_func_issimple(THD *thd, Item *a)
   :Item_long_func_args_geometry(thd, a) {}
965
  longlong val_int() override;
Monty's avatar
Monty committed
966 967 968 969 970
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_issimple") };
    return name;
  }
971
  bool fix_length_and_dec(THD *thd) override { decimals=0; max_length=2; return FALSE; }
972
  decimal_digits_t decimal_precision() const override { return 1; }
973
  Item *do_get_copy(THD *thd) const override
974
  { return get_item_copy<Item_func_issimple>(thd, this); }
975 976
};

977
class Item_func_isclosed: public Item_long_func_args_geometry
978 979
{
public:
980 981
  Item_func_isclosed(THD *thd, Item *a)
   :Item_long_func_args_geometry(thd, a) {}
982
  longlong val_int() override;
Monty's avatar
Monty committed
983 984 985 986 987
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_isclosed") };
    return name;
  }
988
  bool fix_length_and_dec(THD *thd) override { decimals=0; max_length=2; return FALSE; }
989
  decimal_digits_t decimal_precision() const override { return 1; }
990
  Item *do_get_copy(THD *thd) const override
991
  { return get_item_copy<Item_func_isclosed>(thd, this); }
992 993
};

994 995 996
class Item_func_isring: public Item_func_issimple
{
public:
997
  Item_func_isring(THD *thd, Item *a): Item_func_issimple(thd, a) {}
998
  longlong val_int() override;
Monty's avatar
Monty committed
999 1000 1001 1002 1003
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_isring") };
    return name;
  }
1004
  Item *do_get_copy(THD *thd) const override
1005
  { return get_item_copy<Item_func_isring>(thd, this); }
1006 1007
};

1008
class Item_func_dimension: public Item_long_func_args_geometry
1009 1010
{
public:
1011 1012
  Item_func_dimension(THD *thd, Item *a)
   :Item_long_func_args_geometry(thd, a) {}
1013
  longlong val_int() override;
Monty's avatar
Monty committed
1014 1015 1016 1017 1018
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_dimension") };
    return name;
  }
1019
  bool fix_length_and_dec(THD *thd) override
1020
  { max_length= 10; set_maybe_null(); return FALSE; }
1021
  Item *do_get_copy(THD *thd) const override
1022
  { return get_item_copy<Item_func_dimension>(thd, this); }
1023 1024
};

1025 1026

class Item_func_x: public Item_real_func_args_geometry
1027 1028
{
public:
1029
  Item_func_x(THD *thd, Item *a): Item_real_func_args_geometry(thd, a) {}
1030
  double val_real() override;
Monty's avatar
Monty committed
1031 1032 1033 1034 1035
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_x") };
    return name;
  }
1036
  bool fix_length_and_dec(THD *thd) override
1037
  {
1038
    if (Item_real_func::fix_length_and_dec(thd))
1039
      return TRUE;
1040
    set_maybe_null();
1041
    return FALSE;
1042
  }
1043
  Item *do_get_copy(THD *thd) const override
1044
  { return get_item_copy<Item_func_x>(thd, this); }
1045 1046 1047
};


1048
class Item_func_y: public Item_real_func_args_geometry
1049 1050
{
public:
1051
  Item_func_y(THD *thd, Item *a): Item_real_func_args_geometry(thd, a) {}
1052
  double val_real() override;
Monty's avatar
Monty committed
1053 1054 1055 1056 1057
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_y") };
    return name;
  }
1058
  bool fix_length_and_dec(THD *thd) override
1059
  {
1060
    if (Item_real_func::fix_length_and_dec(thd))
1061
      return TRUE;
1062
    set_maybe_null();
1063
    return FALSE;
1064
  }
1065
  Item *do_get_copy(THD *thd) const override
1066
  { return get_item_copy<Item_func_y>(thd, this); }
1067 1068 1069
};


1070
class Item_func_numgeometries: public Item_long_func_args_geometry
1071 1072
{
public:
1073 1074
  Item_func_numgeometries(THD *thd, Item *a)
   :Item_long_func_args_geometry(thd, a) {}
1075
  longlong val_int() override;
Monty's avatar
Monty committed
1076 1077 1078 1079 1080
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_numgeometries") };
    return name;
  }
1081
  bool fix_length_and_dec(THD *thd) override
1082
  { max_length= 10; set_maybe_null(); return FALSE; }
1083
  Item *do_get_copy(THD *thd) const override
1084
  { return get_item_copy<Item_func_numgeometries>(thd, this); }
1085 1086 1087
};


1088
class Item_func_numinteriorring: public Item_long_func_args_geometry
1089 1090
{
public:
1091 1092
  Item_func_numinteriorring(THD *thd, Item *a)
   :Item_long_func_args_geometry(thd, a) {}
1093
  longlong val_int() override;
Monty's avatar
Monty committed
1094 1095 1096 1097 1098
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_numinteriorrings") };
    return name;
  }
1099
  bool fix_length_and_dec(THD *thd) override
1100
  { max_length= 10; set_maybe_null(); return FALSE; }
1101
  Item *do_get_copy(THD *thd) const override
1102
  { return get_item_copy<Item_func_numinteriorring>(thd, this); }
1103 1104 1105
};


1106
class Item_func_numpoints: public Item_long_func_args_geometry
1107 1108
{
public:
1109 1110
  Item_func_numpoints(THD *thd, Item *a)
   :Item_long_func_args_geometry(thd, a) {}
1111
  longlong val_int() override;
Monty's avatar
Monty committed
1112 1113 1114 1115 1116
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_numpoints") };
    return name;
  }
1117
  bool fix_length_and_dec(THD *thd) override
1118
  { max_length= 10; set_maybe_null(); return FALSE; }
1119
  Item *do_get_copy(THD *thd) const override
1120
  { return get_item_copy<Item_func_numpoints>(thd, this); }
1121 1122 1123
};


1124
class Item_func_area: public Item_real_func_args_geometry
1125 1126
{
public:
1127
  Item_func_area(THD *thd, Item *a): Item_real_func_args_geometry(thd, a) {}
1128
  double val_real() override;
Monty's avatar
Monty committed
1129 1130 1131 1132 1133
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_area") };
    return name;
  }
1134
  bool fix_length_and_dec(THD *thd) override
1135
  {
1136
    if (Item_real_func::fix_length_and_dec(thd))
1137
      return TRUE;
1138
    set_maybe_null();
1139
    return FALSE;
1140
  }
1141
  Item *do_get_copy(THD *thd) const override
1142
  { return get_item_copy<Item_func_area>(thd, this); }
1143 1144 1145
};


1146
class Item_func_glength: public Item_real_func_args_geometry
1147 1148 1149
{
  String value;
public:
1150 1151
  Item_func_glength(THD *thd, Item *a)
   :Item_real_func_args_geometry(thd, a) {}
1152
  double val_real() override;
Monty's avatar
Monty committed
1153 1154 1155 1156 1157
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_length") };
    return name;
  }
1158
  bool fix_length_and_dec(THD *thd) override
1159
  {
1160
    if (Item_real_func::fix_length_and_dec(thd))
1161
      return TRUE;
1162
    set_maybe_null();
1163
    return FALSE;
1164
  }
1165
  Item *do_get_copy(THD *thd) const override
1166
  { return get_item_copy<Item_func_glength>(thd, this); }
1167 1168 1169
};


1170
class Item_func_srid: public Item_long_func_args_geometry
1171 1172
{
public:
1173 1174
  Item_func_srid(THD *thd, Item *a)
   :Item_long_func_args_geometry(thd, a) {}
1175
  longlong val_int() override;
Monty's avatar
Monty committed
1176 1177 1178 1179 1180
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("srid") };
    return name;
  }
1181
  bool fix_length_and_dec(THD *thd) override
1182
  { max_length= 10; set_maybe_null(); return FALSE; }
1183
  Item *do_get_copy(THD *thd) const override
1184
  { return get_item_copy<Item_func_srid>(thd, this); }
1185
};
unknown's avatar
unknown committed
1186

1187

1188
class Item_func_distance: public Item_real_func_args_geometry_geometry
1189 1190 1191 1192 1193 1194 1195
{
  String tmp_value1;
  String tmp_value2;
  Gcalc_heap collector;
  Gcalc_function func;
  Gcalc_scan_iterator scan_it;
public:
1196 1197
  Item_func_distance(THD *thd, Item *a, Item *b)
   :Item_real_func_args_geometry_geometry(thd, a, b) {}
1198
  double val_real() override;
Monty's avatar
Monty committed
1199 1200 1201 1202 1203
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_distance") };
    return name;
  }
1204
  Item *do_get_copy(THD *thd) const override
1205
  { return get_item_copy<Item_func_distance>(thd, this); }
1206 1207
};

1208

1209 1210 1211 1212 1213 1214 1215
class Item_func_sphere_distance: public Item_real_func
{
  double spherical_distance_points(Geometry *g1, Geometry *g2,
                                   const double sphere_r);
public:
  Item_func_sphere_distance(THD *thd, List<Item> &list):
    Item_real_func(thd, list) {}
1216
  double val_real() override;
Monty's avatar
Monty committed
1217 1218 1219 1220 1221
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_distance_sphere") };
    return name;
  }
1222
  Item *do_get_copy(THD *thd) const override
Marko Mäkelä's avatar
Marko Mäkelä committed
1223
  { return get_item_copy<Item_func_sphere_distance>(thd, this); }
1224 1225 1226
};


1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253
class Item_func_geohash: public Item_geometry_func
{
  void encode_geohash(String *str, double longitude, double latitude,
                      uint length);
  void set_bit(double &max_value, double &min_value, const double &target_value,
               std::bitset<5> &base_set, const uint &bit_index);
  bool is_invalid_length_field(enum_field_types field_type);
  bool is_invalid_longitude_field(enum_field_types field_type);
  bool is_invalid_latitude_field(enum_field_types field_type);

public:
  Item_func_geohash(THD *thd, Item *point, Item *max_length):
    Item_geometry_func(thd, point, max_length) {}
  Item_func_geohash(THD *thd, Item *longitude, Item *latitude,
                    Item *max_length):
    Item_geometry_func(thd, longitude, latitude, max_length) {}
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_geohash") };
    return name;
  }
  String *val_str(String *) override;
  Item *do_get_copy(THD *thd) const override
  { return get_item_copy<Item_func_geohash>(thd, this); }
};


1254
class Item_func_pointonsurface: public Item_geometry_func_args_geometry
1255 1256 1257 1258 1259 1260
{
  String tmp_value;
  Gcalc_heap collector;
  Gcalc_function func;
  Gcalc_scan_iterator scan_it;
public:
1261 1262
  Item_func_pointonsurface(THD *thd, Item *a)
   :Item_geometry_func_args_geometry(thd, a) {}
Monty's avatar
Monty committed
1263 1264 1265 1266 1267
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_pointonsurface") };
    return name;
  }
1268 1269
  String *val_str(String *) override;
  const Type_handler *type_handler() const override
1270 1271 1272
  {
    return &type_handler_point;
  }
1273
  Item *do_get_copy(THD *thd) const override
1274
  { return get_item_copy<Item_func_pointonsurface>(thd, this); }
1275 1276 1277
};


1278
#ifndef DBUG_OFF
1279
class Item_func_gis_debug: public Item_long_func
1280 1281
{
  public:
1282
    Item_func_gis_debug(THD *thd, Item *a): Item_long_func(thd, a)
1283
    { null_value= false; }
1284
    bool fix_length_and_dec(THD *thd) override { fix_char_length(10); return FALSE; }
Monty's avatar
Monty committed
1285 1286 1287 1288 1289
  LEX_CSTRING func_name_cstring() const override
  {
    static LEX_CSTRING name= {STRING_WITH_LEN("st_gis_debug") };
    return name;
  }
1290 1291
    longlong val_int() override;
    bool check_vcol_func_processor(void *arg) override
1292
    {
1293
      return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
1294
    }
1295
    Item *do_get_copy(THD *thd) const override
1296
    { return get_item_copy<Item_func_gis_debug>(thd, this); }
1297 1298 1299 1300
};
#endif


1301
#define GEOM_NEW(thd, obj_constructor) new (thd->mem_root) obj_constructor
1302
#define GEOM_TYPE(x) (x)
unknown's avatar
unknown committed
1303

1304
#endif /* ITEM_GEOFUNC_INCLUDED */