Commit 33835635 authored by Stefano Petrilli's avatar Stefano Petrilli Committed by Sergei Golubchik

MDEV-34158: Implement the GIS function ST_Geohash

The function returns the geohash corresponding to the input values.
The GIS function ST_GeoHash takes as input:

  (longitude, latitude, max_length), OR
  (point, max_length)

The longitue parameter is a numeric value in the interval [180, -180],
the latitude is a numeric value in the interval [90, -90].
In the case of point, the x coordinate is treated as the latitude and
the y coordinate is treated as the latitude. Even in the case of a
point, the same constraints apply.
The max_length parameter is the upper limit on the resulting string
size and cannot exceed 100.

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 f924cbda
# valid inputs
SELECT ST_GEOHASH(0,0,1);
ST_GEOHASH(0,0,1)
s
SELECT ST_GEOHASH(180,0,20);
ST_GEOHASH(180,0,20)
xbpbpbpbpbpbpbpbpbpb
SELECT ST_GEOHASH(-180,0,20);
ST_GEOHASH(-180,0,20)
80000000000000000000
SELECT ST_GEOHASH(0,90,20);
ST_GEOHASH(0,90,20)
upbpbpbpbpbpbpbpbpbp
SELECT ST_GEOHASH(0,-90,20);
ST_GEOHASH(0,-90,20)
h0000000000000000000
SELECT ST_GEOHASH(180,90,20);
ST_GEOHASH(180,90,20)
zzzzzzzzzzzzzzzzzzzz
SELECT ST_GEOHASH(180,-90,20);
ST_GEOHASH(180,-90,20)
pbpbpbpbpbpbpbpbpbpb
SELECT ST_GEOHASH(-180,90,20);
ST_GEOHASH(-180,90,20)
bpbpbpbpbpbpbpbpbpbp
SELECT ST_GEOHASH(-180,-90,20);
ST_GEOHASH(-180,-90,20)
00000000000000000000
SELECT ST_GEOHASH(100,45,5);
ST_GEOHASH(100,45,5)
y0p05
SELECT ST_GEOHASH(100,-45,10);
ST_GEOHASH(100,-45,10)
q0p0581b0b
SELECT ST_GEOHASH(-100,45,+50);
ST_GEOHASH(-100,45,+50)
cb0bh2n0p0581b0bh2n0p8
SELECT ST_GEOHASH(0.0001,0.0001,10);
ST_GEOHASH(0.0001,0.0001,10)
s0000000d6
SELECT ST_GEOHASH(0.0001,-0.0001,30);
ST_GEOHASH(0.0001,-0.0001,30)
kpbpbpbp6m6e6p6bpntebbpkpnqbuf
SELECT ST_GEOHASH(-0.0001,0.0001,90);
ST_GEOHASH(-0.0001,0.0001,90)
ebpbpbpbtdtktbtpbc6kppbebc9p5q000000000000000000000000000000000000000000000000000000000000
SELECT ST_GEOHASH(-0.0001,-0.0001,100);
ST_GEOHASH(-0.0001,-0.0001,100)
7zzzzzzzmtm7mzm00yd7z00s0y30g60000000000000000000000000000000000000000000000000000000000000000000000
SELECT ST_GEOHASH("",90,10);
ST_GEOHASH("",90,10)
upbpbpbpbp
SELECT ST_GEOHASH(0,"90",10);
ST_GEOHASH(0,"90",10)
upbpbpbpbp
SELECT ST_GEOHASH("0","0",10);
ST_GEOHASH("0","0",10)
s000000000
SELECT ST_GEOHASH(180,90,"20");
ST_GEOHASH(180,90,"20")
zzzzzzzzzzzzzzzzzzzz
SELECT ST_GEOHASH("180","90","20");
ST_GEOHASH("180","90","20")
zzzzzzzzzzzzzzzzzzzz
SELECT ST_GEOHASH("***",90,"20");
ST_GEOHASH("***",90,"20")
upbpbpbpbpbpbpbpbpbp
SELECT ST_GEOHASH(180,"***",20);
ST_GEOHASH(180,"***",20)
xbpbpbpbpbpbpbpbpbpb
SELECT ST_GEOHASH("abcd",90,20);
ST_GEOHASH("abcd",90,20)
upbpbpbpbpbpbpbpbpbp
SELECT ST_GEOHASH(180,"abcd",25-5);
ST_GEOHASH(180,"abcd",25-5)
xbpbpbpbpbpbpbpbpbpb
SELECT ST_GEOHASH(NULL,90,10);
ST_GEOHASH(NULL,90,10)
NULL
SELECT ST_GEOHASH(180,NULL,10);
ST_GEOHASH(180,NULL,10)
NULL
SELECT ST_GEOHASH(180,90,NULL);
ST_GEOHASH(180,90,NULL)
NULL
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),10);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),10)
s000000000
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 0)'),20);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 0)'),20)
xbpbpbpbpbpbpbpbpbpb
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 0)'),25);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 0)'),25)
8000000000000000000002pbp
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 90)'),30);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 90)'),30)
upbpbpbpbpbpbpbpbpbpbpbpbpbpbp
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 -90)'),35);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 -90)'),35)
h000000000000000000001bpbpbpbpbpbpb
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 90)'),40);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 90)'),40)
zzzzzzzzzzzzzzzzzzzzzz
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 -90)'),45);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 -90)'),45)
pbpbpbpbpbpbpbpbpbpbpc
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 90)'),50);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 90)'),50)
bpbpbpbpbpbpbpbpbpbpbr
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 -90)'),55);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 -90)'),55)
0000000000000000000003
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(100 45)'),60);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(100 45)'),60)
y0p0581b0bh2n0p0581b0b
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(100 -45)'),65);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(100 -45)'),65)
q0p0581b0bh2n0p0581b0b
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-100 45)'),70);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-100 45)'),70)
cb0bh2n0p0581b0bh2n0p8
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-100 -45)'),75);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-100 -45)'),75)
3b0bh2n0p0581b0bh2n0p8
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(0.0001 0.0001)'))),80);
ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(0.0001 0.0001)'))),80)
s0000000d6dsd0dzz1ms0zz7z1wzhy00000000000000000000000000000000000000000000000000
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(0.0001 -0.0001)'))),85);
ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(0.0001 -0.0001)'))),85)
kpbpbpbp6m6e6p6bpntebbpkpnqbuf0000000000000000000000000000000000000000000000000000000
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(-0.0001 0.0001)'))),90);
ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(-0.0001 0.0001)'))),90)
ebpbpbpbtdtktbtpbc6kppbebc9p5q000000000000000000000000000000000000000000000000000000000000
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(-0.0001 -0.0001)'))),100);
ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(-0.0001 -0.0001)'))),100)
7zzzzzzzmtm7mzm00yd7z00s0y30g60000000000000000000000000000000000000000000000000000000000000000000000
SELECT ST_GEOHASH(ST_GEOMFROMWKB(0x010100000000000000008066400000000000805640),20);
ST_GEOHASH(ST_GEOMFROMWKB(0x010100000000000000008066400000000000805640),20)
zzzzzzzzzzzzzzzzzzzz
SELECT ST_GEOHASH(ST_GEOMFROMWKB(0x010100000000000000008066C00000000000805640),20);
ST_GEOHASH(ST_GEOMFROMWKB(0x010100000000000000008066C00000000000805640),20)
bpbpbpbpbpbpbpbpbpbp
SELECT ST_GEOHASH(ST_GEOMFROMWKB(0x00000000014066800000000000C056800000000000),20);
ST_GEOHASH(ST_GEOMFROMWKB(0x00000000014066800000000000C056800000000000),20)
pbpbpbpbpbpbpbpbpbpb
SELECT ST_GEOHASH(ST_GEOMFROMWKB(0x0000000001C066800000000000C056800000000000),20);
ST_GEOHASH(ST_GEOMFROMWKB(0x0000000001C066800000000000C056800000000000),20)
00000000000000000000
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),"1");
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),"1")
s
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)')," 10 ");
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)')," 10 ")
s000000000
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),"+100");
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),"+100")
s000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
SELECT ST_GEOHASH(NULL,100);
ST_GEOHASH(NULL,100)
NULL
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-0.0001 -0.0001)'),NULL);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-0.0001 -0.0001)'),NULL)
NULL
SELECT ST_GEOHASH(ST_DIFFERENCE(ST_GEOMFROMTEXT('POINT(180 90)'),ST_GEOMFROMTEXT('POINT(0 0)')),20);
ST_GEOHASH(ST_DIFFERENCE(ST_GEOMFROMTEXT('POINT(180 90)'),ST_GEOMFROMTEXT('POINT(0 0)')),20)
zzzzzzzzzzzzzzzzzzzz
SELECT ST_GEOHASH(ST_DIFFERENCE(ST_GEOMFROMTEXT('POINT(-180 90)'),ST_GEOMFROMTEXT('MULTIPOINT(0 0,100 100)')),20);
ST_GEOHASH(ST_DIFFERENCE(ST_GEOMFROMTEXT('POINT(-180 90)'),ST_GEOMFROMTEXT('MULTIPOINT(0 0,100 100)')),20)
bpbpbpbpbpbpbpbpbpbp
SELECT ST_GEOHASH(ST_INTERSECTION(ST_GEOMFROMTEXT('POINT(180 -90)'),ST_GEOMFROMTEXT('POINT(180 -90)')),20);
ST_GEOHASH(ST_INTERSECTION(ST_GEOMFROMTEXT('POINT(180 -90)'),ST_GEOMFROMTEXT('POINT(180 -90)')),20)
pbpbpbpbpbpbpbpbpbpb
SELECT ST_GEOHASH(ST_INTERSECTION(ST_GEOMFROMTEXT('POINT(-180 -90)'),ST_GEOMFROMTEXT('POINT(-180 -90)')),20);
ST_GEOHASH(ST_INTERSECTION(ST_GEOMFROMTEXT('POINT(-180 -90)'),ST_GEOMFROMTEXT('POINT(-180 -90)')),20)
00000000000000000000
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 90)'),(CAST(10 AS BINARY)));
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 90)'),(CAST(10 AS BINARY)))
zzzzzzzzzz
SELECT ST_GEOHASH((CAST(10 AS BINARY)),20,1);
ST_GEOHASH((CAST(10 AS BINARY)),20,1)
s
SELECT ST_GEOHASH(10,(CAST(20 AS BINARY)),1);
ST_GEOHASH(10,(CAST(20 AS BINARY)),1)
s
SELECT ST_GEOHASH((CAST(10 AS BINARY)),(CAST(20 AS BINARY)),1);
ST_GEOHASH((CAST(10 AS BINARY)),(CAST(20 AS BINARY)),1)
s
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT()'),20);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT()'),20)
NULL
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(1)'),20);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(1)'),20)
NULL
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(1 a)'),20);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(1 a)'),20)
NULL
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180,90)'),20);
ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180,90)'),20)
NULL
# invalid inputs
SELECT ST_GEOHASH(181,0,10);
ERROR HY000: Out of range error: Longitude should be [-180,180] in function ST_GeoHash.
SELECT ST_GEOHASH(1000,90,10);
ERROR HY000: Out of range error: Longitude should be [-180,180] in function ST_GeoHash.
SELECT ST_GEOHASH(180.0000000000001,-90,10);
ERROR HY000: Out of range error: Longitude should be [-180,180] in function ST_GeoHash.
SELECT ST_GEOHASH(-181,0,10);
ERROR HY000: Out of range error: Longitude should be [-180,180] in function ST_GeoHash.
SELECT ST_GEOHASH(-1000,90,10);
ERROR HY000: Out of range error: Longitude should be [-180,180] in function ST_GeoHash.
SELECT ST_GEOHASH(-180.0000000000001,-90,10);
ERROR HY000: Out of range error: Longitude should be [-180,180] in function ST_GeoHash.
SELECT ST_GEOHASH(0,91,10);
ERROR HY000: Out of range error: Latitude should be [-90,90] in function ST_GeoHash.
SELECT ST_GEOHASH(180,500,10);
ERROR HY000: Out of range error: Latitude should be [-90,90] in function ST_GeoHash.
SELECT ST_GEOHASH(-180,90.0000000000001,10);
ERROR HY000: Out of range error: Latitude should be [-90,90] in function ST_GeoHash.
SELECT ST_GEOHASH(0,-91,10);
ERROR HY000: Out of range error: Latitude should be [-90,90] in function ST_GeoHash.
SELECT ST_GEOHASH(180,-500,10);
ERROR HY000: Out of range error: Latitude should be [-90,90] in function ST_GeoHash.
SELECT ST_GEOHASH(-180,-90.0000000000001,10);
ERROR HY000: Out of range error: Latitude should be [-90,90] in function ST_GeoHash.
SELECT ST_GEOHASH(180,90,0);
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(-180,90,-1);
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(180,-90,-100);
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(-180,-90,101);
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(0,90,1000);
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH("181",90,20);
ERROR HY000: Out of range error: Longitude should be [-180,180] in function ST_GeoHash.
SELECT ST_GEOHASH("-181",90,20);
ERROR HY000: Out of range error: Longitude should be [-180,180] in function ST_GeoHash.
SELECT ST_GEOHASH(180,"91",20);
ERROR HY000: Out of range error: Latitude should be [-90,90] in function ST_GeoHash.
SELECT ST_GEOHASH(180,"-91",20);
ERROR HY000: Out of range error: Latitude should be [-90,90] in function ST_GeoHash.
SELECT ST_GEOHASH(180,90,"0");
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(180,90,"-1");
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(180,90,"-100");
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(180,90,"101");
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(180,90,"1000");
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(180,90,"");
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(180,90,"****");
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH();
ERROR 42000: Incorrect parameter count in the call to native function 'ST_GEOHASH'
SELECT ST_GEOHASH(1);
ERROR 42000: Incorrect parameter count in the call to native function 'ST_GEOHASH'
SELECT ST_GEOHASH(1,2);
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
SELECT ST_GEOHASH(, ,);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' ,)' at line 1
SELECT ST_GEOHASH(1,2,);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1
SELECT ST_GEOHASH(*,0,10);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '*,0,10)' at line 1
SELECT ST_GEOHASH(0,*,10);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '*,10)' at line 1
SELECT ST_GEOHASH(0,0,*);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '*)' at line 1
SELECT ST_GEOHASH(a,90,10);
ERROR 42S22: Unknown column 'a' in 'field list'
SELECT ST_GEOHASH(180,p,10);
ERROR 42S22: Unknown column 'p' in 'field list'
SELECT ST_GEOHASH(180,90,z);
ERROR 42S22: Unknown column 'z' in 'field list'
SELECT ST_GEOHASH((CAST(180 AS DATE)),90,10);
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
SELECT ST_GEOHASH(180,(CAST(90 AS DATE)),10);
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(181 0)'),10);
ERROR HY000: Out of range error: Longitude should be [-180,180] in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(1000 90)'),10);
ERROR HY000: Out of range error: Longitude should be [-180,180] in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180.0000000000001 -90)'),10);
ERROR HY000: Out of range error: Longitude should be [-180,180] in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-181 0)'),10);
ERROR HY000: Out of range error: Longitude should be [-180,180] in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-1000 90)'),10);
ERROR HY000: Out of range error: Longitude should be [-180,180] in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180.0000000000001 -90)'),10);
ERROR HY000: Out of range error: Longitude should be [-180,180] in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 91)'),10);
ERROR HY000: Out of range error: Latitude should be [-90,90] in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 500)'),10);
ERROR HY000: Out of range error: Latitude should be [-90,90] in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 90.0000000000001)'),10);
ERROR HY000: Out of range error: Latitude should be [-90,90] in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 -91)'),10);
ERROR HY000: Out of range error: Latitude should be [-90,90] in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 -500)'),10);
ERROR HY000: Out of range error: Latitude should be [-90,90] in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 -90.0000000000001)'),10);
ERROR HY000: Out of range error: Latitude should be [-90,90] in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 90)'),0);
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 -90)'),-1);
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 90)'),-100);
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 -90)'),101);
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),10000);
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(180 90)'))),"0");
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(180 -90)'))),"-1");
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(-180 90)'))),"-100");
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(-180 -90)'))),"101");
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(0 0)'))),"10000");
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)')," ");
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),"***");
ERROR HY000: Out of range error: max geohash length value in function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'));
ERROR 42000: Incorrect parameter count in the call to native function 'ST_GEOHASH'
SELECT ST_GEOHASH(ST_GEOMFROMTEXT(),20);
ERROR 42000: Incorrect parameter count in the call to native function 'ST_GEOMFROMTEXT'
SELECT ST_GEOHASH((ST_GEOMFROMTEXT('POINT(0 0)'),);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1
SELECT ST_GEOHASH(,10);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '10)' at line 1
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),a);
ERROR 42S22: Unknown column 'a' in 'field list'
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('LINESTRING(0 0,10 10)'),10);
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POLYGON((0 0,10 0,10 10,0 10,0 0))'),10);
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('MULTIPOINT(0 0,10 10)'),10);
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('MULTILINESTRING((0 0,10 10),(20 20,30 30))'),10);
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0),(4 4,4 6,6 6,6 4,4 4)))'),10);
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(POINT(0 0))'),10);
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 90)'),20.0001);
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 90)'),(CAST(10 AS DATE)));
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
SELECT ST_GEOHASH(ST_INTERSECTION(ST_GEOMFROMTEXT('POINT(180 90)'),ST_GEOMFROMTEXT('POINT(1 1)')),20);
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
SELECT ST_GEOHASH(ST_UNION(ST_GEOMFROMTEXT('POINT(180 90)'),ST_GEOMFROMTEXT('POINT(-180 -90)')),20);
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
SELECT ST_GEOHASH(ST_DIFFERENCE(ST_GEOMFROMTEXT('POINT(180 90)'),ST_GEOMFROMTEXT('MULTIPOINT(0 0,180 90)')),20);
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
SELECT ST_GEOHASH(ST_SYMDIFFERENCE(ST_GEOMFROMTEXT('POINT(180 90)'),ST_GEOMFROMTEXT('POINT(0 0)')),20);
ERROR 22023: Invalid GIS data provided to function ST_GeoHash.
# Copyright (c) 2014, Oracle and/or its affiliates
# Copyright (c) 2024, MariaDB Corporation.
#
# 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
# the Free Software Foundation; version 2 of the License.
#
# 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
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
-- disable_warnings
#####################################################################
# ST_GEOHASH()
#####################################################################
# Check for all valid inputs
--echo # valid inputs
SELECT ST_GEOHASH(0,0,1);
SELECT ST_GEOHASH(180,0,20);
SELECT ST_GEOHASH(-180,0,20);
SELECT ST_GEOHASH(0,90,20);
SELECT ST_GEOHASH(0,-90,20);
SELECT ST_GEOHASH(180,90,20);
SELECT ST_GEOHASH(180,-90,20);
SELECT ST_GEOHASH(-180,90,20);
SELECT ST_GEOHASH(-180,-90,20);
SELECT ST_GEOHASH(100,45,5);
SELECT ST_GEOHASH(100,-45,10);
SELECT ST_GEOHASH(-100,45,+50);
SELECT ST_GEOHASH(0.0001,0.0001,10);
SELECT ST_GEOHASH(0.0001,-0.0001,30);
SELECT ST_GEOHASH(-0.0001,0.0001,90);
SELECT ST_GEOHASH(-0.0001,-0.0001,100);
SELECT ST_GEOHASH("",90,10);
SELECT ST_GEOHASH(0,"90",10);
SELECT ST_GEOHASH("0","0",10);
SELECT ST_GEOHASH(180,90,"20");
SELECT ST_GEOHASH("180","90","20");
SELECT ST_GEOHASH("***",90,"20");
SELECT ST_GEOHASH(180,"***",20);
SELECT ST_GEOHASH("abcd",90,20);
SELECT ST_GEOHASH(180,"abcd",25-5);
SELECT ST_GEOHASH(NULL,90,10);
SELECT ST_GEOHASH(180,NULL,10);
SELECT ST_GEOHASH(180,90,NULL);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),10);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 0)'),20);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 0)'),25);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 90)'),30);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 -90)'),35);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 90)'),40);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 -90)'),45);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 90)'),50);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 -90)'),55);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(100 45)'),60);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(100 -45)'),65);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-100 45)'),70);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-100 -45)'),75);
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(0.0001 0.0001)'))),80);
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(0.0001 -0.0001)'))),85);
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(-0.0001 0.0001)'))),90);
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(-0.0001 -0.0001)'))),100);
SELECT ST_GEOHASH(ST_GEOMFROMWKB(0x010100000000000000008066400000000000805640),20);
SELECT ST_GEOHASH(ST_GEOMFROMWKB(0x010100000000000000008066C00000000000805640),20);
SELECT ST_GEOHASH(ST_GEOMFROMWKB(0x00000000014066800000000000C056800000000000),20);
SELECT ST_GEOHASH(ST_GEOMFROMWKB(0x0000000001C066800000000000C056800000000000),20);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),"1");
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)')," 10 ");
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),"+100");
SELECT ST_GEOHASH(NULL,100);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-0.0001 -0.0001)'),NULL);
SELECT ST_GEOHASH(ST_DIFFERENCE(ST_GEOMFROMTEXT('POINT(180 90)'),ST_GEOMFROMTEXT('POINT(0 0)')),20);
SELECT ST_GEOHASH(ST_DIFFERENCE(ST_GEOMFROMTEXT('POINT(-180 90)'),ST_GEOMFROMTEXT('MULTIPOINT(0 0,100 100)')),20);
SELECT ST_GEOHASH(ST_INTERSECTION(ST_GEOMFROMTEXT('POINT(180 -90)'),ST_GEOMFROMTEXT('POINT(180 -90)')),20);
SELECT ST_GEOHASH(ST_INTERSECTION(ST_GEOMFROMTEXT('POINT(-180 -90)'),ST_GEOMFROMTEXT('POINT(-180 -90)')),20);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 90)'),(CAST(10 AS BINARY)));
SELECT ST_GEOHASH((CAST(10 AS BINARY)),20,1);
SELECT ST_GEOHASH(10,(CAST(20 AS BINARY)),1);
SELECT ST_GEOHASH((CAST(10 AS BINARY)),(CAST(20 AS BINARY)),1);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT()'),20);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(1)'),20);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(1 a)'),20);
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180,90)'),20);
# Invalid inputs
--echo # invalid inputs
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(181,0,10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(1000,90,10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(180.0000000000001,-90,10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(-181,0,10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(-1000,90,10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(-180.0000000000001,-90,10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(0,91,10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(180,500,10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(-180,90.0000000000001,10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(0,-91,10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(180,-500,10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(-180,-90.0000000000001,10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(180,90,0);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(-180,90,-1);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(180,-90,-100);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(-180,-90,101);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(0,90,1000);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH("181",90,20);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH("-181",90,20);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(180,"91",20);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(180,"-91",20);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(180,90,"0");
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(180,90,"-1");
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(180,90,"-100");
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(180,90,"101");
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(180,90,"1000");
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(180,90,"");
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(180,90,"****");
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT ST_GEOHASH();
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT ST_GEOHASH(1);
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH(1,2);
# --error ER_GIS_INVALID_DATA
# SELECT ST_GEOHASH(-100,-45,100.1);
--error ER_PARSE_ERROR
SELECT ST_GEOHASH(, ,);
--error ER_PARSE_ERROR
SELECT ST_GEOHASH(1,2,);
--error ER_PARSE_ERROR
SELECT ST_GEOHASH(*,0,10);
--error ER_PARSE_ERROR
SELECT ST_GEOHASH(0,*,10);
--error ER_PARSE_ERROR
SELECT ST_GEOHASH(0,0,*);
--error ER_BAD_FIELD_ERROR
SELECT ST_GEOHASH(a,90,10);
--error ER_BAD_FIELD_ERROR
SELECT ST_GEOHASH(180,p,10);
--error ER_BAD_FIELD_ERROR
SELECT ST_GEOHASH(180,90,z);
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH((CAST(180 AS DATE)),90,10);
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH(180,(CAST(90 AS DATE)),10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(181 0)'),10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(1000 90)'),10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180.0000000000001 -90)'),10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-181 0)'),10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-1000 90)'),10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180.0000000000001 -90)'),10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 91)'),10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 500)'),10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 90.0000000000001)'),10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 -91)'),10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 -500)'),10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 -90.0000000000001)'),10);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 90)'),0);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 -90)'),-1);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 90)'),-100);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(-180 -90)'),101);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),10000);
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(180 90)'))),"0");
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(180 -90)'))),"-1");
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(-180 90)'))),"-100");
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(-180 -90)'))),"101");
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMWKB(ST_ASWKB(ST_GEOMFROMTEXT('POINT(0 0)'))),"10000");
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)')," ");
--error ER_STD_OUT_OF_RANGE_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),"***");
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'));
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT ST_GEOHASH(ST_GEOMFROMTEXT(),20);
--error ER_PARSE_ERROR
SELECT ST_GEOHASH((ST_GEOMFROMTEXT('POINT(0 0)'),);
--error ER_PARSE_ERROR
SELECT ST_GEOHASH(,10);
--error ER_BAD_FIELD_ERROR
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(0 0)'),a);
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('LINESTRING(0 0,10 10)'),10);
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POLYGON((0 0,10 0,10 10,0 10,0 0))'),10);
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('MULTIPOINT(0 0,10 10)'),10);
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('MULTILINESTRING((0 0,10 10),(20 20,30 30))'),10);
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0),(4 4,4 6,6 6,6 4,4 4)))'),10);
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(POINT(0 0))'),10);
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 90)'),20.0001);
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH(ST_GEOMFROMTEXT('POINT(180 90)'),(CAST(10 AS DATE)));
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH(ST_INTERSECTION(ST_GEOMFROMTEXT('POINT(180 90)'),ST_GEOMFROMTEXT('POINT(1 1)')),20);
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH(ST_UNION(ST_GEOMFROMTEXT('POINT(180 90)'),ST_GEOMFROMTEXT('POINT(-180 -90)')),20);
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH(ST_DIFFERENCE(ST_GEOMFROMTEXT('POINT(180 90)'),ST_GEOMFROMTEXT('MULTIPOINT(0 0,180 90)')),20);
--error ER_GIS_INVALID_DATA
SELECT ST_GEOHASH(ST_SYMDIFFERENCE(ST_GEOMFROMTEXT('POINT(180 90)'),ST_GEOMFROMTEXT('POINT(0 0)')),20);
......@@ -36,6 +36,12 @@
#include "item_geofunc.h"
#include "item_create.h"
#define MAX_LONGITUDE 180
#define MIN_LONGITUDE -180
#define MAX_LATITUDE 90
#define MIN_LATITUDE -90
#define MAX_GEOHASH_LENGTH 100
#define MIN_GEOHASH_LENGTH 0
bool Item_geometry_func::fix_length_and_dec(THD *thd)
{
......@@ -2651,6 +2657,175 @@ double Item_func_sphere_distance::spherical_distance_points(Geometry *g1,
}
String *Item_func_geohash::val_str(String *str)
{
DBUG_ASSERT(fixed());
double latitude, longitude;
uint geohash_length;
Item* length_field;
null_value= 1;
if (arg_count == 2)
{
Geometry_buffer buffer;
Geometry *geometry;
String tmp;
String *wkb= args[0]->val_str(&tmp);
if (args[0]->null_value || args[1]->null_value)
return 0;
length_field= args[1];
geometry = Geometry::construct(&buffer, wkb->ptr(), wkb->length());
if (!geometry ||
geometry->get_class_info()->m_type_id != Geometry::wkb_point ||
geometry->get_x(&longitude) || geometry->get_y(&latitude))
{
my_error(ER_GIS_INVALID_DATA, MYF(0), "ST_GeoHash");
return 0;
}
}
else
{
if (args[0]->null_value || args[1]->null_value || args[2]->null_value)
return 0;
if (is_invalid_longitude_field(args[0]->field_type()) ||
is_invalid_latitude_field(args[1]->field_type()))
{
my_error(ER_GIS_INVALID_DATA, MYF(0), "ST_GeoHash");
return 0;
}
longitude= args[0]->val_real();
latitude= args[1]->val_real();
length_field= args[2];
}
if (is_invalid_length_field(length_field->field_type()))
{
my_error(ER_GIS_INVALID_DATA, MYF(0), "ST_GeoHash");
return 0;
}
if (longitude > MAX_LONGITUDE || longitude < MIN_LONGITUDE)
{
my_error(ER_STD_OUT_OF_RANGE_ERROR, MYF(0),
"Longitude should be [-180,180]", "ST_GeoHash");
return 0;
}
if (latitude > MAX_LATITUDE || latitude < MIN_LATITUDE)
{
my_error(ER_STD_OUT_OF_RANGE_ERROR, MYF(0),
"Latitude should be [-90,90]", "ST_GeoHash");
return 0;
}
geohash_length= static_cast<uint>(length_field->val_int());
if (geohash_length <= MIN_GEOHASH_LENGTH ||
geohash_length > MAX_GEOHASH_LENGTH)
{
my_error(ER_STD_OUT_OF_RANGE_ERROR, MYF(0), "max geohash length value",
"ST_GeoHash");
return 0;
}
str->length(0);
str->set_charset(&my_charset_latin1);
if (str->reserve(geohash_length))
return 0;
encode_geohash(str, longitude, latitude, geohash_length);
null_value= 0;
return str;
}
bool Item_func_geohash::is_invalid_length_field(enum_field_types field_type)
{
switch (field_type)
{
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_NULL:
case MYSQL_TYPE_VARCHAR:
return false;
default:
return true;
}
}
bool Item_func_geohash::is_invalid_longitude_field(enum_field_types field_type)
{
switch (field_type)
{
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_NEWDECIMAL:
return false;
default:
return true;
}
}
bool Item_func_geohash::is_invalid_latitude_field(enum_field_types field_type)
{
return is_invalid_longitude_field(field_type);
}
void Item_func_geohash::encode_geohash(String *str, double longitude,
double latitude, uint length)
{
constexpr char BASE32[]= "0123456789bcdefghjkmnpqrstuvwxyz";
double tmp_max_latitude= MAX_LATITUDE;
double tmp_min_latitude= MIN_LATITUDE;
double tmp_max_longitude= MAX_LONGITUDE;
double tmp_min_longitude= MIN_LONGITUDE;
std::bitset<5> base_set;
bool switch_bit= true;
for (uint i=0; i<length; ++i)
{
for (uint bit_index=0; bit_index<5; ++bit_index)
{
set_bit(switch_bit ? tmp_max_longitude : tmp_max_latitude,
switch_bit ? tmp_min_longitude : tmp_min_latitude,
switch_bit ? longitude : latitude,
base_set, bit_index);
switch_bit = !switch_bit;
}
uint char_index= base_set.to_ulong();
DBUG_ASSERT(char_index <= 31);
str->append(BASE32[char_index]);
if (latitude == ((tmp_max_latitude + tmp_min_latitude) / 2.0) &&
longitude == ((tmp_max_longitude + tmp_min_longitude) / 2.0))
break;
}
}
void Item_func_geohash::set_bit(double &max_value, double &min_value, const double &target_value,
std::bitset<5> &base_set, const uint &bit_index)
{
double mid_value= (max_value + min_value) / 2.0;
if (target_value >= mid_value)
{
base_set[4 - bit_index]= 1;
min_value= mid_value;
return;
}
base_set[4 - bit_index]= 0;
max_value= mid_value;
}
String *Item_func_pointonsurface::val_str(String *str)
{
Gcalc_operation_transporter trn(&func, &collector);
......@@ -3012,6 +3187,57 @@ Create_func_distance_sphere::create_native(THD *thd, const LEX_CSTRING *name,
}
class Create_func_geohash : public Create_native_func
{
public:
Item *create_native(THD *thd, const LEX_CSTRING *name, List<Item> *item_list)
override;
static Create_func_geohash s_singleton;
protected:
Create_func_geohash() = default;
virtual ~Create_func_geohash() = default;
};
Item*
Create_func_geohash::create_native(THD *thd, const LEX_CSTRING *name,
List<Item> *item_list)
{
Item *func= NULL;
int arg_count= 0;
if (item_list != NULL)
arg_count= item_list->elements;
switch (arg_count) {
case 2:
{
Item *point= item_list->pop();
Item *max_length= item_list->pop();
func= new (thd->mem_root) Item_func_geohash(thd, point, max_length);
break;
}
case 3:
{
Item *longitude= item_list->pop();
Item *latitude= item_list->pop();
Item *max_length= item_list->pop();
func= new (thd->mem_root) Item_func_geohash(thd, longitude, latitude, max_length);
break;
}
default:
{
my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str);
break;
}
}
return func;
}
class Create_func_endpoint : public Create_func_arg1
{
public:
......@@ -3863,6 +4089,7 @@ Create_func_dimension Create_func_dimension::s_singleton;
Create_func_disjoint Create_func_disjoint::s_singleton;
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_endpoint Create_func_endpoint::s_singleton;
Create_func_envelope Create_func_envelope::s_singleton;
Create_func_equals Create_func_equals::s_singleton;
......@@ -3983,6 +4210,7 @@ static Native_func_registry func_array_geom[] =
{ { STRING_WITH_LEN("POLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
{ { STRING_WITH_LEN("POLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
{ { STRING_WITH_LEN("POLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
{ { STRING_WITH_LEN("GEOHASH") }, GEOM_BUILDER(Create_func_geohash)},
{ { 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)},
......@@ -4063,6 +4291,7 @@ static Native_func_registry func_array_geom[] =
{ { STRING_WITH_LEN("ST_X") }, GEOM_BUILDER(Create_func_x)},
{ { STRING_WITH_LEN("ST_Y") }, GEOM_BUILDER(Create_func_y)},
{ { 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("TOUCHES") }, GEOM_BUILDER(Create_func_touches)},
{ { STRING_WITH_LEN("WITHIN") }, GEOM_BUILDER(Create_func_within)},
{ { STRING_WITH_LEN("X") }, GEOM_BUILDER(Create_func_x)},
......
......@@ -20,6 +20,7 @@
/* This file defines all spatial functions */
#include <bitset>
#include "sql_type_geom.h"
#include "item.h"
#include "gstream.h"
......@@ -1223,6 +1224,33 @@ class Item_func_sphere_distance: public Item_real_func
};
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); }
};
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