Skip to content

Commit b5bc2fa

Browse files
Implement STGeometryType for geometry and geography types (babelfish-for-postgresql#4509)
Implemented the STGeometryType() method for both sys.GEOMETRY and sys.GEOGRAPHY types, extending the existing geospatial functionality in Babelfish. This function returns the geometry type name (Point, LineString, Polygon, etc.) with full TSQL compatibility. Changes Made Function Implementations: STGeometryType for sys.GEOMETRY - Returns geometry type name with proper validation STGeometryType for sys.GEOGRAPHY - Returns geography type name with same behavior Utilizes PostGIS functions with necessary adjustments for TSQL compatibility Strips 'ST_' prefix from PostGIS type names to match TSQL Server format Task: BABEL-6310 Signed-off by: gopalgv gopalgv@amazon.com
1 parent 35a82c4 commit b5bc2fa

14 files changed

+1890
-2
lines changed

contrib/babelfishpg_common/sql/geography.sql

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,25 @@ CREATE OR REPLACE FUNCTION sys.STDimension(geom sys.GEOGRAPHY)
433433
END;
434434
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;
435435

436+
--STGeomType
437+
CREATE OR REPLACE FUNCTION sys.STGeometryType(geog sys.GEOGRAPHY)
438+
RETURNS sys.NVARCHAR(4000)
439+
AS $$
440+
DECLARE
441+
geom_type text;
442+
BEGIN
443+
IF STIsValid(geog) = 0 THEN
444+
RAISE EXCEPTION 'This operation cannot be completed because the instance is not valid';
445+
END IF;
446+
geom_type := sys.ST_GeometryType(geog);
447+
448+
IF geom_type LIKE 'ST\_%' ESCAPE '\' THEN
449+
RETURN substr(geom_type, 4);
450+
END IF;
451+
RAISE EXCEPTION 'Unexpected geometry type format: %. Expected ST_* prefix.', geom_type;
452+
END;
453+
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;
454+
436455
-- STDisjoint
437456
-- Checks if two geometries have no points in common
438457
CREATE OR REPLACE FUNCTION sys.STDisjoint(geom1 sys.GEOGRAPHY, geom2 sys.GEOGRAPHY)

contrib/babelfishpg_common/sql/geometry.sql

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,27 @@ CREATE OR REPLACE FUNCTION sys.STDimension(geom sys.GEOMETRY)
427427
END IF;
428428
END;
429429
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;
430+
431+
--STGeomType
432+
CREATE OR REPLACE FUNCTION sys.STGeometryType(geom sys.GEOMETRY)
433+
RETURNS sys.NVARCHAR(4000)
434+
AS $$
435+
DECLARE
436+
geom_type text;
437+
BEGIN
438+
IF STIsValid(geom) = 0 THEN
439+
RAISE EXCEPTION 'This operation cannot be completed because the instance is not valid';
440+
END IF;
441+
442+
geom_type := sys.ST_GeometryType(geom);
443+
444+
IF geom_type LIKE 'ST\_%' ESCAPE '\' THEN
445+
RETURN substr(geom_type, 4);
446+
END IF;
447+
448+
RAISE EXCEPTION 'Unexpected geometry type format: %. Expected ST_* prefix.', geom_type;
449+
END;
450+
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;
430451
431452
-- STDisjoint
432453
-- Checks if two geometries have no points in common
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,46 @@
11
-------------------------------------------------------
22
---- Include changes related to spatial types here ----
33
-------------------------------------------------------
4+
--STGeomType
5+
6+
--Geometry
7+
CREATE OR REPLACE FUNCTION sys.STGeometryType(geom sys.GEOMETRY)
8+
RETURNS sys.NVARCHAR(4000)
9+
AS $$
10+
DECLARE
11+
geom_type text;
12+
BEGIN
13+
IF STIsValid(geom) = 0 THEN
14+
RAISE EXCEPTION 'This operation cannot be completed because the instance is not valid';
15+
END IF;
16+
17+
geom_type := sys.ST_GeometryType(geom);
18+
19+
IF geom_type LIKE 'ST\_%' ESCAPE '\' THEN
20+
RETURN substr(geom_type, 4);
21+
END IF;
22+
23+
RAISE EXCEPTION 'Unexpected geometry type format: %. Expected ST_* prefix.', geom_type;
24+
END;
25+
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;
26+
27+
--Geography
28+
29+
CREATE OR REPLACE FUNCTION sys.STGeometryType(geog sys.GEOGRAPHY)
30+
RETURNS sys.NVARCHAR(4000)
31+
AS $$
32+
DECLARE
33+
geom_type text;
34+
BEGIN
35+
IF STIsValid(geog) = 0 THEN
36+
RAISE EXCEPTION 'This operation cannot be completed because the instance is not valid';
37+
END IF;
38+
geom_type := sys.ST_GeometryType(geog);
39+
40+
IF geom_type LIKE 'ST\_%' ESCAPE '\' THEN
41+
RETURN substr(geom_type, 4);
42+
END IF;
43+
44+
RAISE EXCEPTION 'Unexpected geometry type format: %. Expected ST_* prefix.', geom_type;
45+
END;
46+
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;

contrib/babelfishpg_tsql/antlr/TSqlLexer.g4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ STDISJOINT: 'STDisjoint';
980980
STDISTANCE: 'STDistance';
981981
STEQUALS: 'STEquals';
982982
STGEOMFROMTEXT: 'STGeomFromText';
983+
STGEOMETRYTYPE: 'STGeometryType';
983984
STINTERSECTS: 'STIntersects';
984985
STISCLOSED: 'STIsClosed';
985986
STISEMPTY: 'STIsEmpty';

contrib/babelfishpg_tsql/antlr/TSqlParser.g4

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3942,6 +3942,7 @@ geospatial_func_no_arg
39423942
| STASBINARY
39433943
| STAREA
39443944
| STDIMENSION
3945+
| STGEOMETRYTYPE
39453946
| STISCLOSED
39463947
| STISEMPTY
39473948
| STISVALID
@@ -5080,6 +5081,7 @@ keyword
50805081
| STDISJOINT
50815082
| STDISTANCE
50825083
| STEQUALS
5084+
| STGEOMETRYTYPE
50835085
| STGEOMFROMTEXT
50845086
| STINTERSECTS
50855087
| STISCLOSED
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
USE TestGeospatialMethods3_DB;
2+
3+
DROP VIEW TestGeospatialMethods3_STGeometryType_GEOM_View_db;
4+
DROP VIEW TestGeospatialMethods3_STGeometryType_GEOG_View_db;
5+
6+
DROP TABLE TestGeospatialMethods3_STGeometryType_GEOM_db;
7+
DROP TABLE TestGeospatialMethods3_STGeometryType_GEOG_db;
8+
9+
USE MASTER;
10+
11+
DROP VIEW TestGeospatialMethods3_STGeometryType_GEOM_View_Temp;
12+
DROP VIEW TestGeospatialMethods3_STGeometryType_GEOG_View_Temp;
13+
14+
DROP TABLE TestGeospatialMethods3_STGeometryType_GEOM_Temp;
15+
DROP TABLE TestGeospatialMethods3_STGeometryType_GEOG_Temp;
16+
17+
DROP DATABASE TestGeospatialMethods3_DB;
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
CREATE DATABASE TestGeospatialMethods3_DB;
2+
3+
USE TestGeospatialMethods3_DB;
4+
5+
CREATE TABLE TestGeospatialMethods3_STGeometryType_GEOM_db (ID INT PRIMARY KEY, GeomColumn geometry);
6+
7+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_db (ID, GeomColumn) VALUES ( 1, geometry::STGeomFromText('POINT(1 2)', 4326) );
8+
~~ROW COUNT: 1~~
9+
10+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_db (ID, GeomColumn) VALUES ( 2, geometry::STGeomFromText('LINESTRING(0 0, 1 1, 2 2)', 4326) );
11+
~~ROW COUNT: 1~~
12+
13+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_db (ID, GeomColumn) VALUES ( 3, geometry::STGeomFromText('POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))', 4326) );
14+
~~ROW COUNT: 1~~
15+
16+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_db (ID, GeomColumn) VALUES ( 4, geometry::STGeomFromText('POINT(0 0 100)', 4326) );
17+
~~ROW COUNT: 1~~
18+
19+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_db (ID, GeomColumn) VALUES ( 5, geometry::STGeomFromText('LINESTRING(0 0, 1 1, 2 2, 3 3)', 4326) );
20+
~~ROW COUNT: 1~~
21+
22+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_db (ID, GeomColumn) VALUES ( 6, geometry::STGeomFromText('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0), (0.2 0.2, 0.8 0.2, 0.8 0.8, 0.2 0.8, 0.2 0.2))', 4326) );
23+
~~ROW COUNT: 1~~
24+
25+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_db (ID, GeomColumn) VALUES ( 7, geometry::STGeomFromText('POINT(1 1 100 200)', 4326) );
26+
~~ROW COUNT: 1~~
27+
28+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_db (ID, GeomColumn) VALUES ( 8, geometry::STPointFromText('POINT EMPTY', 4326) );
29+
~~ROW COUNT: 1~~
30+
31+
32+
CREATE TABLE TestGeospatialMethods3_STGeometryType_GEOG_db (ID INT PRIMARY KEY, GeogColumn geography);
33+
34+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_db (ID, GeogColumn) VALUES ( 1, geography::STGeomFromText('POINT(-122.34 47.65)', 4326) );
35+
~~ROW COUNT: 1~~
36+
37+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_db (ID, GeogColumn) VALUES ( 2, geography::STGeomFromText('LINESTRING(-122.36 47.65, -122.34 47.66, -122.32 47.65)', 4326) );
38+
~~ROW COUNT: 1~~
39+
40+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_db (ID, GeogColumn) VALUES ( 3, geography::STGeomFromText('POLYGON((-122.35 47.64, -122.33 47.64, -122.33 47.66, -122.35 47.66, -122.35 47.64))', 4326) );
41+
~~ROW COUNT: 1~~
42+
43+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_db (ID, GeogColumn) VALUES ( 4, geography::STGeomFromText('POINT(-122.34 47.65 100)', 4326) );
44+
~~ROW COUNT: 1~~
45+
46+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_db (ID, GeogColumn) VALUES ( 5, geography::STGeomFromText('LINESTRING(-122.36 47.65, -122.34 47.66, -122.32 47.65, -122.30 47.66)', 4326) );
47+
~~ROW COUNT: 1~~
48+
49+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_db (ID, GeogColumn) VALUES ( 6, geography::STGeomFromText('POLYGON((-122.35 47.64, -122.33 47.64, -122.33 47.66, -122.35 47.66, -122.35 47.64), (-122.34 47.645, -122.335 47.645, -122.335 47.655, -122.34 47.655, -122.34 47.645))', 4326) );
50+
~~ROW COUNT: 1~~
51+
52+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_db (ID, GeogColumn) VALUES ( 7, geography::STGeomFromText('POINT(-122.34 47.65 200 300)', 4326) );
53+
~~ROW COUNT: 1~~
54+
55+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_db (ID, GeogColumn) VALUES ( 8, geography::STPointFromText('POINT EMPTY', 4326) );
56+
~~ROW COUNT: 1~~
57+
58+
59+
CREATE VIEW TestGeospatialMethods3_STGeometryType_GEOM_View_db AS SELECT ID, GeomColumn.STGeometryType() AS GeomType FROM TestGeospatialMethods3_STGeometryType_GEOM_db;
60+
61+
CREATE VIEW TestGeospatialMethods3_STGeometryType_GEOG_View_db AS SELECT ID, GeogColumn.STGeometryType() AS GeogType FROM TestGeospatialMethods3_STGeometryType_GEOG_db;
62+
63+
USE MASTER
64+
65+
CREATE TABLE TestGeospatialMethods3_STGeometryType_GEOM_Temp (ID INT PRIMARY KEY, GeomColumn geometry);
66+
67+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_Temp (ID, GeomColumn) VALUES ( 1, geometry::STGeomFromText('POINT(1 2)', 4326) );
68+
~~ROW COUNT: 1~~
69+
70+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_Temp (ID, GeomColumn) VALUES ( 2, geometry::STGeomFromText('LINESTRING(0 0, 1 1, 2 2)', 4326) );
71+
~~ROW COUNT: 1~~
72+
73+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_Temp (ID, GeomColumn) VALUES ( 3, geometry::STGeomFromText('POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))', 4326) );
74+
~~ROW COUNT: 1~~
75+
76+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_Temp (ID, GeomColumn) VALUES ( 4, geometry::STGeomFromText('POINT(0 0 100)', 4326) );
77+
~~ROW COUNT: 1~~
78+
79+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_Temp (ID, GeomColumn) VALUES ( 5, geometry::STGeomFromText('LINESTRING(0 0, 1 1, 2 2, 3 3)', 4326) );
80+
~~ROW COUNT: 1~~
81+
82+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_Temp (ID, GeomColumn) VALUES ( 6, geometry::STGeomFromText('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0), (0.2 0.2, 0.8 0.2, 0.8 0.8, 0.2 0.8, 0.2 0.2))', 4326) );
83+
~~ROW COUNT: 1~~
84+
85+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_Temp (ID, GeomColumn) VALUES ( 7, geometry::STGeomFromText('POINT(1 1 100 200)', 4326) );
86+
~~ROW COUNT: 1~~
87+
88+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOM_Temp (ID, GeomColumn) VALUES ( 8, geometry::STPointFromText('POINT EMPTY', 4326) );
89+
~~ROW COUNT: 1~~
90+
91+
92+
CREATE TABLE TestGeospatialMethods3_STGeometryType_GEOG_Temp (ID INT PRIMARY KEY, GeogColumn geography);
93+
94+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_Temp (ID, GeogColumn) VALUES ( 1, geography::STGeomFromText('POINT(-122.34 47.65)', 4326) );
95+
~~ROW COUNT: 1~~
96+
97+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_Temp (ID, GeogColumn) VALUES ( 2, geography::STGeomFromText('LINESTRING(-122.36 47.65, -122.34 47.66, -122.32 47.65)', 4326) );
98+
~~ROW COUNT: 1~~
99+
100+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_Temp (ID, GeogColumn) VALUES ( 3, geography::STGeomFromText('POLYGON((-122.35 47.64, -122.33 47.64, -122.33 47.66, -122.35 47.66, -122.35 47.64))', 4326) );
101+
~~ROW COUNT: 1~~
102+
103+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_Temp (ID, GeogColumn) VALUES ( 4, geography::STGeomFromText('POINT(-122.34 47.65 100)', 4326) );
104+
~~ROW COUNT: 1~~
105+
106+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_Temp (ID, GeogColumn) VALUES ( 5, geography::STGeomFromText('LINESTRING(-122.36 47.65, -122.34 47.66, -122.32 47.65, -122.30 47.66)', 4326) );
107+
~~ROW COUNT: 1~~
108+
109+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_Temp (ID, GeogColumn) VALUES ( 6, geography::STGeomFromText('POLYGON((-122.35 47.64, -122.33 47.64, -122.33 47.66, -122.35 47.66, -122.35 47.64), (-122.34 47.645, -122.335 47.645, -122.335 47.655, -122.34 47.655, -122.34 47.645))', 4326) );
110+
~~ROW COUNT: 1~~
111+
112+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_Temp (ID, GeogColumn) VALUES ( 7, geography::STGeomFromText('POINT(-122.34 47.65 200 300)', 4326) );
113+
~~ROW COUNT: 1~~
114+
115+
INSERT INTO TestGeospatialMethods3_STGeometryType_GEOG_Temp (ID, GeogColumn) VALUES ( 8, geography::STPointFromText('POINT EMPTY', 4326) );
116+
~~ROW COUNT: 1~~
117+
118+
119+
CREATE VIEW TestGeospatialMethods3_STGeometryType_GEOM_View_Temp AS SELECT ID, GeomColumn.STGeometryType() AS GeomType FROM TestGeospatialMethods3_STGeometryType_GEOM_Temp;
120+
121+
CREATE VIEW TestGeospatialMethods3_STGeometryType_GEOG_View_Temp AS SELECT ID, GeogColumn.STGeometryType() AS GeogType FROM TestGeospatialMethods3_STGeometryType_GEOG_Temp;
122+

0 commit comments

Comments
 (0)