Commit 7c6c55e9 authored by Stefano Petrilli's avatar Stefano Petrilli Committed by Sergei Golubchik

MDEV-34160: Implements ST_LongFromGeoHash

The GIS function ST_LongFromGeoHash takes in input a geohash and returns
its longitude.
The longitude is returned as a numeric value in the interval
[180, -180].
If the argument is NULL, the return value is NULL. If the argument is
invalid, an ER_GIS_INVALID_DATA is thrown.

Author: StefanoPetrilli <stefanop_1999@hotmail.it>
Co-authored-by: default avatarkevincheng2 <chengyf112@gmail.com>
Co-authored-by: default avatarCatalin Besleaga <catalin.besleaga@oracle.com>
Co-authored-by: default avatarGleb Shchepa <gleb.shchepa@oracle.com>
Co-authored-by: default avatarTatiana Azundris Nuernberg <tatjana.nuernberg@oracle.com>
Co-authored-by: default avatarMartin Hansson <martin.hansson@oracle.com>
Co-authored-by: default avatarDeepa Dixit <deepa.dixit@oracle.com>
Co-authored-by: default avatarHans H Melby <hans.h.melby@oracle.com>
Co-authored-by: default avatarJens Even Berg Blomsøy <jens.even.blomsoy@oracle.com>
Co-authored-by: default avatarErlend Dahl <erlend.dahl@oracle.com>
Co-authored-by: default avatarNorvald H. Ryeng <norvald.ryeng@oracle.com>
Co-authored-by: default avatarBennyWang <benny.wang@oracle.com>
Co-authored-by: default avatarDavid.Zhao <david.zhao@oracle.com>
Co-authored-by: default avatarErik Froseth <erik.froseth@oracle.com>
parent 3ac93a19
......@@ -2672,7 +2672,7 @@ String *Item_func_geohash::val_str(String *str)
{
DBUG_ASSERT(fixed());
double latitude, longitude;
uint geohash_length;
int geohash_length;
Item* length_field;
null_value= 1;
......@@ -2683,7 +2683,7 @@ String *Item_func_geohash::val_str(String *str)
String tmp;
String *wkb= args[0]->val_str(&tmp);
if (args[0]->null_value || args[1]->null_value)
if (args[0]->null_value)
return 0;
length_field= args[1];
......@@ -2698,7 +2698,7 @@ String *Item_func_geohash::val_str(String *str)
}
else
{
if (args[0]->null_value || args[1]->null_value || args[2]->null_value)
if (args[0]->null_value || args[1]->null_value)
return 0;
if (is_invalid_longitude_field(args[0]->field_type()) ||
......@@ -2710,6 +2710,10 @@ String *Item_func_geohash::val_str(String *str)
longitude= args[0]->val_real();
latitude= args[1]->val_real();
if (args[0]->null_value || args[1]->null_value)
return 0;
length_field= args[2];
}
......@@ -2734,6 +2738,9 @@ String *Item_func_geohash::val_str(String *str)
}
geohash_length= static_cast<uint>(length_field->val_int());
if (length_field->null_value)
geohash_length= MAX_GEOHASH_LENGTH;
if (geohash_length <= MIN_GEOHASH_LENGTH ||
geohash_length > MAX_GEOHASH_LENGTH)
{
......@@ -2760,7 +2767,9 @@ bool Item_func_geohash::is_invalid_length_field(enum_field_types field_type)
{
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_NULL:
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_LONG_BLOB:
return false;
default:
return true;
......@@ -2775,6 +2784,9 @@ bool Item_func_geohash::is_invalid_longitude_field(enum_field_types field_type)
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_NEWDECIMAL:
case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_LONG_BLOB:
return false;
default:
return true;
......@@ -3008,6 +3020,8 @@ bool Item_func_latlongfromgeohash::is_invalid_geohash_field(
{
case MYSQL_TYPE_NULL:
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_GEOMETRY:
return false;
default:
return true;
......@@ -3515,6 +3529,23 @@ class Create_func_latfromgeohash : public Create_func_arg1
virtual ~Create_func_latfromgeohash() = default;
};
class Create_func_longfromgeohash : public Create_func_arg1
{
public:
Item *create_1_arg(THD *thd, Item *arg1) override
{
return new (thd->mem_root) Item_func_longfromgeohash(thd, arg1);
}
static Create_func_longfromgeohash s_singleton;
protected:
Create_func_longfromgeohash() = default;
virtual ~Create_func_longfromgeohash() = default;
};
class Create_func_endpoint : public Create_func_arg1
{
public:
......@@ -4369,6 +4400,7 @@ Create_func_distance Create_func_distance::s_singleton;
Create_func_distance_sphere Create_func_distance_sphere::s_singleton;
Create_func_geohash Create_func_geohash::s_singleton;
Create_func_latfromgeohash Create_func_latfromgeohash ::s_singleton;
Create_func_longfromgeohash Create_func_longfromgeohash ::s_singleton;
Create_func_endpoint Create_func_endpoint::s_singleton;
Create_func_envelope Create_func_envelope::s_singleton;
Create_func_equals Create_func_equals::s_singleton;
......@@ -4494,6 +4526,7 @@ static Native_func_registry func_array_geom[] =
{ { STRING_WITH_LEN("POLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
{ { STRING_WITH_LEN("GEOHASH") }, GEOM_BUILDER(Create_func_geohash)},
{ { STRING_WITH_LEN("LATFROMGEOHASH") }, GEOM_BUILDER(Create_func_latfromgeohash)},
{ { STRING_WITH_LEN("LONGFROMGEOHASH") }, GEOM_BUILDER(Create_func_longfromgeohash)},
{ { STRING_WITH_LEN("SRID") }, GEOM_BUILDER(Create_func_srid)},
{ { STRING_WITH_LEN("ST_AREA") }, GEOM_BUILDER(Create_func_area)},
{ { STRING_WITH_LEN("STARTPOINT") }, GEOM_BUILDER(Create_func_startpoint)},
......@@ -4577,6 +4610,7 @@ static Native_func_registry func_array_geom[] =
{ { STRING_WITH_LEN("ST_DISTANCE_SPHERE") }, GEOM_BUILDER(Create_func_distance_sphere)},
{ { STRING_WITH_LEN("ST_GEOHASH") }, GEOM_BUILDER(Create_func_geohash)},
{ { STRING_WITH_LEN("ST_LATFROMGEOHASH") }, GEOM_BUILDER(Create_func_latfromgeohash)},
{ { STRING_WITH_LEN("ST_LONGFROMGEOHASH") }, GEOM_BUILDER(Create_func_longfromgeohash)},
{ { STRING_WITH_LEN("TOUCHES") }, GEOM_BUILDER(Create_func_touches)},
{ { STRING_WITH_LEN("WITHIN") }, GEOM_BUILDER(Create_func_within)},
{ { STRING_WITH_LEN("X") }, GEOM_BUILDER(Create_func_x)},
......
......@@ -1285,6 +1285,21 @@ class Item_func_latfromgeohash: public Item_func_latlongfromgeohash
};
class Item_func_longfromgeohash: public Item_func_latlongfromgeohash
{
public:
Item_func_longfromgeohash(THD *thd, Item *a)
:Item_func_latlongfromgeohash(thd, a, true) {}
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("st_longfromgeohash") };
return name;
}
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_func_longfromgeohash>(thd, this); }
};
class Item_func_pointonsurface: public Item_geometry_func_args_geometry
{
String tmp_value;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment