MySQL 8.4.0
Source Code Documentation
item_geofunc.cc File Reference

This file defines all spatial functions. More...

#include "sql/item_geofunc.h"
#include <algorithm>
#include <cfloat>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <limits>
#include <map>
#include <memory>
#include <new>
#include <string>
#include <utility>
#include <boost/geometry/algorithms/centroid.hpp>
#include <boost/geometry/algorithms/convex_hull.hpp>
#include <boost/geometry/algorithms/detail/calculate_point_order.hpp>
#include <boost/geometry/strategies/strategies.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include "lex_string.h"
#include "m_string.h"
#include "my_alloc.h"
#include "my_byteorder.h"
#include "my_compiler.h"
#include "my_config.h"
#include "my_dbug.h"
#include "mysql/strings/int2str.h"
#include "mysql/strings/m_ctype.h"
#include "sql-common/json_dom.h"
#include "sql/current_thd.h"
#include "sql/dd/cache/dictionary_client.h"
#include "sql/dd/types/spatial_reference_system.h"
#include "sql/derror.h"
#include "sql/gis/area.h"
#include "sql/gis/buffer.h"
#include "sql/gis/distance.h"
#include "sql/gis/distance_sphere.h"
#include "sql/gis/frechet_distance.h"
#include "sql/gis/geometries.h"
#include "sql/gis/geometries_cs.h"
#include "sql/gis/hausdorff_distance.h"
#include "sql/gis/is_simple.h"
#include "sql/gis/is_valid.h"
#include "sql/gis/length.h"
#include "sql/gis/line_interpolate.h"
#include "sql/gis/relops.h"
#include "sql/gis/ring_flip_visitor.h"
#include "sql/gis/setops.h"
#include "sql/gis/simplify.h"
#include "sql/gis/srid.h"
#include "sql/gis/st_units_of_measure.h"
#include "sql/gis/transform.h"
#include "sql/gis/wkb.h"
#include "sql/gstream.h"
#include "sql/item_geofunc_internal.h"
#include "sql/options_parser.h"
#include "sql/parse_tree_node_base.h"
#include "sql/psi_memory_key.h"
#include "sql/sql_class.h"
#include "sql/sql_error.h"
#include "sql/sql_exception_handler.h"
#include "sql/sql_lex.h"
#include "sql/srs_fetcher.h"
#include "sql/system_variables.h"
#include "sql/thr_malloc.h"
#include "string_with_len.h"
#include "template_utils.h"
#include "unsafe_string_append.h"

Classes

class  Point_accumulator
 Accumulate a geometry's all vertex points into a multipoint. More...
 
class  Geometry_grouper< Base_type >
 Retrieve from a geometry collection geometries of the same base type into a multi-xxx geometry object. More...
 

Namespaces

namespace  boost
 Tag dispatch for custom Role_properties.
 
namespace  boost::geometry
 
namespace  boost::geometry::cs
 

Enumerations

enum class  ConvertUnitResult { kError , kNull , kOk }
 

Functions

static bool is_item_null (Item *item)
 Check if a Item is considered to be a SQL NULL value. More...
 
static bool is_item_geometry_type (Item *item)
 Check if an Item is considered to be a geometry type. More...
 
template<typename Point_range >
bool is_colinear (const Point_range &ls)
 Check whether all points in the sequence container are colinear. More...
 
static bool validate_srid_arg (Item *arg, gis::srid_t *srid, bool *null_value, const char *func_name)
 Get an SRID from an item and check that it's within bounds. More...
 
static bool verify_cartesian_srs (const Geometry *g, const char *func_name)
 Verify that a geometry is in a Cartesian SRS. More...
 
static bool verify_srid_is_defined (gis::srid_t srid)
 Verify that an SRID is defined. More...
 
static const char * wkbtype_to_geojson_type (Geometry::wkbType type)
 Converts a wkbType to the corresponding GeoJSON type. More...
 
static bool append_coordinates (Geometry::wkb_parser *parser, Json_array *array, MBR *mbr, const char *calling_function, int max_decimal_digits, bool add_bounding_box)
 Append a GeoJSON array with coordinates to the writer at the current position. More...
 
static bool append_linestring (Geometry::wkb_parser *parser, Json_array *points, MBR *mbr, const char *calling_function, int max_decimal_digits, bool add_bounding_box)
 Append a GeoJSON LineString object to the writer at the current position. More...
 
static bool append_polygon (Geometry::wkb_parser *parser, Json_array *polygon_rings, MBR *mbr, const char *calling_function, int max_decimal_digits, bool add_bounding_box)
 Append a GeoJSON Polygon object to the writer at the current position. More...
 
static bool append_bounding_box (MBR *mbr, Json_object *geometry)
 Appends a GeoJSON bounding box to the rapidjson output buffer. More...
 
static bool append_crs (Json_object *geometry, bool add_short_crs_urn, bool add_long_crs_urn, uint32 geometry_srid)
 Appends a GeoJSON CRS object to the rapidjson output buffer. More...
 
static bool append_geometry (Geometry::wkb_parser *parser, Json_object *geometry, bool is_root_object, MBR *mbr, const char *calling_function, int max_decimal_digits, bool add_bounding_box, bool add_short_crs_urn, bool add_long_crs_urn, uint32 geometry_srid)
 Reads a WKB GEOMETRY from input and writes the equivalent GeoJSON to the output. More...
 
bool geometry_to_json (Json_wrapper *wr, String *swkb, const char *calling_function, int max_decimal_digits, bool add_bounding_box, bool add_short_crs_urn, bool add_long_crs_urn, uint32 *geometry_srid)
 The contract for this function is found in item_json_func.h. More...
 
template<typename Coordsys >
bool geometry_collection_centroid (const Geometry *geom, typename BG_models< Coordsys >::Point *respt, bool *null_value)
 
static ConvertUnitResult ConvertUnit (Item *to_query_expression, const dd::Spatial_reference_system *srs, const char *function_name, double *length)
 ConvertUnit converts length to from the unit used in srs, to the unit in to_uint read as a string. More...
 

Detailed Description

This file defines all spatial functions.

Enumeration Type Documentation

◆ ConvertUnitResult

enum class ConvertUnitResult
strong
Enumerator
kError 
kNull 
kOk 

Function Documentation

◆ append_bounding_box()

static bool append_bounding_box ( MBR mbr,
Json_object geometry 
)
static

Appends a GeoJSON bounding box to the rapidjson output buffer.

Parameters
mbrBounding box to write.
geometryThe JSON object to append the bounding box to.
Returns
false on success, true otherwise.

◆ append_coordinates()

static bool append_coordinates ( Geometry::wkb_parser parser,
Json_array array,
MBR mbr,
const char *  calling_function,
int  max_decimal_digits,
bool  add_bounding_box 
)
static

Append a GeoJSON array with coordinates to the writer at the current position.

The WKB parser must be positioned at the beginning of the coordinates. There must exactly two coordinates in the array (x and y). The coordinates are rounded to the number of decimals specified in the variable max_decimal_digits.:

max_decimal_digits == 2: 12.789 => 12.79 10 => 10.00

Parameters
parserWKB parser with position set to the beginning of the coordinates.
arrayJSON array to append the result to.
mbrA bounding box, which will be updated with data from the coordinates.
calling_functionName of user-invoked function
max_decimal_digitsMax length of decimal numbers
add_bounding_boxTrue if a bounding box should be added
Returns
false on success, true otherwise.

◆ append_crs()

static bool append_crs ( Json_object geometry,
bool  add_short_crs_urn,
bool  add_long_crs_urn,
uint32  geometry_srid 
)
static

Appends a GeoJSON CRS object to the rapidjson output buffer.

If both add_long_crs_urn and add_short_crs_urn is specified, the long CRS URN is preferred as mentioned in the GeoJSON specification:

"OGC CRS URNs such as "urn:ogc:def:crs:OGC:1.3:CRS84" shall be preferred over legacy identifiers such as "EPSG:4326""

Parameters
geometryThe JSON object to append the CRS object to.
add_short_crs_urnTrue if we should add short format CRS URN
add_long_crs_urnTrue if we should add long format CRS URN
geometry_sridSpacial Reference System Identifier being used
Returns
false on success, true otherwise.

◆ append_geometry()

static bool append_geometry ( Geometry::wkb_parser parser,
Json_object geometry,
bool  is_root_object,
MBR mbr,
const char *  calling_function,
int  max_decimal_digits,
bool  add_bounding_box,
bool  add_short_crs_urn,
bool  add_long_crs_urn,
uint32  geometry_srid 
)
static

Reads a WKB GEOMETRY from input and writes the equivalent GeoJSON to the output.

If a GEOMETRYCOLLECTION is found, this function will call itself for each GEOMETRY in the collection.

Parameters
parserThe WKB input to read from, positioned at the start of GEOMETRY header.
geometryJSON object to append the result to.
is_root_objectIndicating if the current GEOMETRY is the root object in the output GeoJSON.
mbrA bounding box, which will be updated with data from all the GEOMETRIES found in the input.
calling_functionName of the user-invoked function
max_decimal_digitsMax length of decimal numbers
add_bounding_boxTrue if a bounding box should be added
add_short_crs_urnTrue if we should add short format CRS URN
add_long_crs_urnTrue if we should add long format CRS URN
geometry_sridSpacial Reference System Identifier being used
Returns
false on success, true otherwise.

◆ append_linestring()

static bool append_linestring ( Geometry::wkb_parser parser,
Json_array points,
MBR mbr,
const char *  calling_function,
int  max_decimal_digits,
bool  add_bounding_box 
)
static

Append a GeoJSON LineString object to the writer at the current position.

The parser must be positioned after the LineString header, and there must be at least one coordinate array in the linestring.

Parameters
parserWKB parser with position set to after the LineString header.
pointsJSON array to append the result to.
mbrA bounding box, which will be updated with data from the LineString.
calling_functionName of user-invoked function
max_decimal_digitsMax length of decimal numbers
add_bounding_boxTrue if a bounding box should be added
Returns
false on success, true otherwise.

◆ append_polygon()

static bool append_polygon ( Geometry::wkb_parser parser,
Json_array polygon_rings,
MBR mbr,
const char *  calling_function,
int  max_decimal_digits,
bool  add_bounding_box 
)
static

Append a GeoJSON Polygon object to the writer at the current position.

The parser must be positioned after the Polygon header, and all coordinate arrays must contain at least one value.

Parameters
parserWKB parser with position set to after the Polygon header.
polygon_ringsJSON array to append the result to.
mbrA bounding box, which will be updated with data from the Polygon.
calling_functionName of user-invoked function
max_decimal_digitsMax length of decimal numbers
add_bounding_boxTrue if a bounding box should be added
Returns
false on success, true otherwise.

◆ ConvertUnit()

static ConvertUnitResult ConvertUnit ( Item to_query_expression,
const dd::Spatial_reference_system srs,
const char *  function_name,
double *  length 
)
static

ConvertUnit converts length to from the unit used in srs, to the unit in to_uint read as a string.

Srs's linear unit is used to ocnvert back to meters and to_query_expression is used to find the conversion factor from meters to the wanted unit.

Parameters
[in]to_query_expressionAn item treated as the name of the unit we want to convert to.
[in]srsThe spatial reference system the length is assumed to come from.
[in]function_nameName of the SQL function to report errors as.
[in,out]lengthThe length to convert to another unit.
Return values
kErrorAn error has occurred, this could be overflows, unsupported units, srs without unit (SRID 0), conversion errors.
kNullThe result is sql null, because the to_query_expression was null.
kOkSuccess.

◆ geometry_collection_centroid()

template<typename Coordsys >
bool geometry_collection_centroid ( const Geometry geom,
typename BG_models< Coordsys >::Point *  respt,
bool *  null_value 
)

◆ geometry_to_json()

bool geometry_to_json ( Json_wrapper wr,
String swkb,
const char *  calling_function,
int  max_decimal_digits,
bool  add_bounding_box,
bool  add_short_crs_urn,
bool  add_long_crs_urn,
uint32 geometry_srid 
)

The contract for this function is found in item_json_func.h.

Turn a GEOMETRY value into a JSON value per the GeoJSON specification revision 1.0.

◆ is_colinear()

template<typename Point_range >
bool is_colinear ( const Point_range &  ls)

Check whether all points in the sequence container are colinear.

Parameters
lsa sequence of points with no duplicates.
Returns
true if the points are colinear, false otherwise.

◆ is_item_geometry_type()

static bool is_item_geometry_type ( Item item)
static

Check if an Item is considered to be a geometry type.

We do the following checks to determine if the Item is a geometry type:

  • NULL is considered a valid geometry type.
  • If the field_type is MYSQL_TYPE_GEOMETRY, it is indeed a geometry.
  • If the type() is PARAM_ITEM, we accept it as a geometry type. This is used to allow for parameter markers.
  • If the collation of the Item is binary, we accept it as a geometry type. This is used to allow for user-defined variables.
Parameters
itemThe Item to verify as a geometry type.
Returns
true if the Item is considered to be a geometry type, false otherwise.

◆ is_item_null()

static bool is_item_null ( Item item)
static

Check if a Item is considered to be a SQL NULL value.

This includes NULL in the following forms:

  - Literal NULL (e.g. SELECT NULL;)
  - NULL in a user-defined variable (SET @foo = NULL;)
  - NULL in prepared statements (PREPARE stmt FROM 'SELECT ?';).

If a SQL NULL is provided via an user-defined variable, it will be detected as a FUNC_ITEM with MYSQL_TYPE_MEDIUM_BLOB as the field type.

Parameters
itemThe item to check for SQL NULL.
Returns
true if the input is considered as NULL, false otherwise.

◆ validate_srid_arg()

static bool validate_srid_arg ( Item arg,
gis::srid_t srid,
bool *  null_value,
const char *  func_name 
)
static

Get an SRID from an item and check that it's within bounds.

If the item is NULL, set null_value.

The value must be representable as a 32 bit unsigned integer. If the value is outside this range, an error is flagged.

Parameters
[in]argItem that holds the SRID
[out]sridWhere to store the SRID
[out]null_valueWhere to store the null_value
[in]func_nameFunction name to use in error messages
Return values
trueAn error has occurred
falseSuccess

◆ verify_cartesian_srs()

static bool verify_cartesian_srs ( const Geometry g,
const char *  func_name 
)
static

Verify that a geometry is in a Cartesian SRS.

If the SRID is undefined, or if the SRS is geographic, raise an error.

Parameters
[in]gThe geometry to check.
[in]func_nameThe function name to use in error messages.
Return values
trueAn error has occurred (and my_error has been called).
falseSuccess.

◆ verify_srid_is_defined()

static bool verify_srid_is_defined ( gis::srid_t  srid)
static

Verify that an SRID is defined.

If the SRID is undefined, raise an error.

Parameters
[in]sridThe SRID to check
Return values
trueAn error has occurred (and my_error has been called).
falseSuccess.

◆ wkbtype_to_geojson_type()

static const char * wkbtype_to_geojson_type ( Geometry::wkbType  type)
static

Converts a wkbType to the corresponding GeoJSON type.

Parameters
typeThe WKB Type to convert.
Returns
The corresponding GeoJSON type, or NULL if no such type exists.