Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/jdbc-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ jobs:
cd $timestamp
mv $timestamp.diff ../replication-output-diff.diff
mv "$timestamp"_runSummary.log ../replication-run-summary.log

- name: Upload Run Summary
if: always() && steps.test-file-rename.outcome == 'success'
uses: actions/upload-artifact@v4
Expand Down
36 changes: 36 additions & 0 deletions contrib/babelfishpg_common/sql/geography.sql
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,32 @@ CREATE OR REPLACE FUNCTION sys.STDimension(geom sys.GEOGRAPHY)
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;

--STLength
CREATE OR REPLACE FUNCTION sys.STLength(geom sys.GEOGRAPHY)
RETURNS float8
AS $$
DECLARE
geom_type text;
BEGIN
IF sys.STIsEmpty(geom) = 1 THEN
RETURN 0;
END IF;

IF sys.STIsValid(geom) = 0 THEN
RAISE EXCEPTION 'The geography instance is not valid';
END IF;
-- Get the geometry type
geom_type := sys.ST_GeometryType(geom);

-- Polygon types - use ST_Perimeter (sum of all ring lengths)
IF geom_type IN ('ST_Polygon', 'ST_MultiPolygon') THEN
RETURN sys.STPerimeter_helper(sys.Geography__STFlipCoordinates(geom));
ELSE
RETURN sys.STLength_helper(sys.Geography__STFlipCoordinates(geom));
END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;

-- STDisjoint
-- Checks if two geometries have no points in common
CREATE OR REPLACE FUNCTION sys.STDisjoint(geom1 sys.GEOGRAPHY, geom2 sys.GEOGRAPHY)
Expand Down Expand Up @@ -632,6 +658,16 @@ CREATE OR REPLACE FUNCTION sys.STDimension_helper(sys.GEOGRAPHY)
RETURNS integer
AS '$libdir/postgis-3','LWGEOM_dimension'
LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.STLength_helper(geom sys.GEOGRAPHY)
RETURNS float8
AS '$libdir/postgis-3', 'geography_length'
LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.STPerimeter_helper(geom sys.GEOGRAPHY)
RETURNS float8
AS '$libdir/postgis-3', 'geography_perimeter'
LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.STIntersects_helper(geom1 sys.GEOGRAPHY, geom2 sys.GEOGRAPHY)
RETURNS sys.BIT
Expand Down
31 changes: 31 additions & 0 deletions contrib/babelfishpg_common/sql/geometry.sql
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,27 @@ CREATE OR REPLACE FUNCTION sys.STDimension(geom sys.GEOMETRY)
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;

-- STLength
CREATE OR REPLACE FUNCTION sys.STLength(geom sys.GEOMETRY)
RETURNS float8
AS $$
DECLARE
geom_type text;
BEGIN
IF sys.STIsEmpty(geom)=1 THEN
RETURN 0;
END IF;

geom_type := sys.ST_GeometryType(geom);

IF geom_type IN ('ST_Polygon', 'ST_MultiPolygon') THEN
RETURN sys.STPerimeter_helper(geom);
ELSE
RETURN sys.STLength_helper(geom);
END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;

-- STDisjoint
-- Checks if two geometries have no points in common
CREATE OR REPLACE FUNCTION sys.STDisjoint(geom1 sys.GEOMETRY, geom2 sys.GEOMETRY)
Expand Down Expand Up @@ -623,6 +644,16 @@ CREATE OR REPLACE FUNCTION sys.STDimension_helper(sys.GEOMETRY)
AS '$libdir/postgis-3','LWGEOM_dimension'
LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.STLength_helper(sys.GEOMETRY)
RETURNS float8
AS '$libdir/postgis-3','LWGEOM_length2d_linestring'
LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.STPerimeter_helper(sys.GEOMETRY)
RETURNS float8
AS '$libdir/postgis-3','LWGEOM_perimeter2d_poly'
LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.STIntersects_helper(geom1 sys.GEOMETRY, geom2 sys.GEOMETRY)
RETURNS sys.BIT
AS '$libdir/postgis-3','ST_Intersects'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,69 @@
-------------------------------------------------------
---- Include changes related to spatial types here ----
-------------------------------------------------------
-- STLength
CREATE OR REPLACE FUNCTION sys.STLength(geom sys.GEOMETRY)
RETURNS float8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have we verified whether it is float4 or float8?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes i have verified it

AS $$
DECLARE
geom_type text;
BEGIN
IF sys.STIsEmpty(geom)=1 THEN
RETURN 0;
END IF;

geom_type := sys.ST_GeometryType(geom);
-- Polygon types - use ST_Perimeter (sum of all ring lengths)
IF geom_type IN ('ST_Polygon', 'ST_MultiPolygon') THEN
RETURN sys.STPerimeter_helper(geom);
ELSE
RETURN sys.STLength_helper(geom);
END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.STLength_helper(geom sys.GEOMETRY)
RETURNS float8
AS '$libdir/postgis-3', 'LWGEOM_length2d_linestring'
LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.STPerimeter_helper(sys.GEOMETRY)
RETURNS float8
AS '$libdir/postgis-3','LWGEOM_perimeter2d_poly'
LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.STLength(geom sys.GEOGRAPHY)
RETURNS float8
AS $$
DECLARE
geom_type text;
BEGIN
-- EMPTY → 0
IF sys.STIsEmpty(geom) = 1 THEN
RETURN 0;
END IF;

IF sys.STIsValid(geom) = 0 THEN
RAISE EXCEPTION 'The geography instance is not valid';
END IF;
-- Get the geometry type
geom_type := sys.ST_GeometryType(geom);

-- Polygon types - use ST_Perimeter (sum of all ring lengths)
IF geom_type IN ('ST_Polygon', 'ST_MultiPolygon') THEN
RETURN sys.STPerimeter_helper(sys.Geography__STFlipCoordinates(geom));
ELSE
RETURN sys.STLength_helper(sys.Geography__STFlipCoordinates(geom));
END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.STLength_helper(geom sys.GEOGRAPHY)
RETURNS float8
AS '$libdir/postgis-3', 'geography_length'
LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.STPerimeter_helper(geom sys.GEOGRAPHY)
RETURNS float8
AS '$libdir/postgis-3', 'geography_perimeter'
LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE;
1 change: 1 addition & 0 deletions contrib/babelfishpg_tsql/antlr/TSqlLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,7 @@ STDEVP: S T D E V P;
STDIMENSION: 'STDimension';
STDISJOINT: 'STDisjoint';
STDISTANCE: 'STDistance';
STLENGTH: 'STLength';
STEQUALS: 'STEquals';
STGEOMFROMTEXT: 'STGeomFromText';
STINTERSECTS: 'STIntersects';
Expand Down
2 changes: 2 additions & 0 deletions contrib/babelfishpg_tsql/antlr/TSqlParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -3942,6 +3942,7 @@ geospatial_func_no_arg
| STASBINARY
| STAREA
| STDIMENSION
| STLENGTH
| STISCLOSED
| STISEMPTY
| STISVALID
Expand Down Expand Up @@ -5077,6 +5078,7 @@ keyword
| STDEV
| STDEVP
| STDIMENSION
| STLENGTH
| STDISJOINT
| STDISTANCE
| STEQUALS
Expand Down
8 changes: 8 additions & 0 deletions test/JDBC/expected/Test-spatial-functions-2-vu-cleanup.out
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,16 @@ DROP VIEW TestGeospatialMethods_empty_ValFromGeomTemp

DROP VIEW TestGeospatialMethods_empty_TextFromGeomTemp

DROP VIEW TestGeospatialMethods_lengthTemp

DROP VIEW TestGeospatialMethods_lengthGeogTemp

DROP TABLE TestGeospatialMethods_SPATIALPOINTGEOM_dttemp

DROP TABLE TestGeospatialMethods_SPATIALPOINTGEOG_dttemp

DROP TABLE TestGeospatialMethods_GeomTableTemp

DROP TABLE TestGeospatialMethods_GeogTableTemp

DROP DATABASE TestGeospatialMethods_DB
75 changes: 75 additions & 0 deletions test/JDBC/expected/Test-spatial-functions-2-vu-prepare.out
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,78 @@ CREATE VIEW TestGeospatialMethods_closed_TextFromGeogTemp AS SELECT location.ST
CREATE VIEW TestGeospatialMethods_empty_ValFromGeomTemp AS SELECT location.STIsEmpty() FROM TestGeospatialMethods_SPATIALPOINTGEOM_dttemp ORDER BY location.STX;

CREATE VIEW TestGeospatialMethods_empty_TextFromGeomTemp AS SELECT location.STIsEmpty() AS Dimension FROM TestGeospatialMethods_SPATIALPOINTGEOG_dttemp ORDER BY location.Lat;

CREATE TABLE TestGeospatialMethods_GeomTableTemp ( ID INT PRIMARY KEY, GeomColumn geometry );
INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (1, geometry::STGeomFromText('LINESTRING(0 0, 3 0)', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (2, geometry::STGeomFromText('LINESTRING(0 0, 3 4)', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (3, geometry::STGeomFromText('LINESTRING(0 0, 5 0, 5 5)', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (4, geometry::STGeomFromText('LINESTRING(0 0, 1 1, 2 0, 3 1, 4 0)', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (5, geometry::STGeomFromText('LINESTRING(0 0, 10 0, 10 10, 0 10, 0 0)', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (6, geometry::STGeomFromText('LINESTRING(0 0, 1 0, 2 0, 3 0, 4 0, 5 0)', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (7, geometry::STGeomFromText('LINESTRING(0 0 0, 3 0 4)', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (8, geometry::STGeomFromText('LINESTRING(0 0 0, 3 0 4)', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (9, geometry::STGeomFromText('LINESTRING(0 0 0, 1 1 1, 2 2 2)', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (10, geometry::STGeomFromText('LINESTRING(0 0 0 0, 3 0 4 1)', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (11, geometry::STGeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (12, geometry::STGeomFromText('POLYGON((0 0, 5 0, 5 5, 0 5, 0 0))', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (13, geometry::STGeomFromText('POLYGON((0 0, 20 0, 20 20, 0 20, 0 0), (5 5, 15 5, 15 15, 5 15, 5 5))', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (14, geometry::STGeomFromText('POLYGON((0 0, 3 0, 0 4, 0 0))', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (15, geometry::STGeomFromText('LINESTRING(0 0 0, 3 4 5)', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (16, geometry::STGeomFromText('LINESTRING(0 0 0 0, 3 4 5 10)', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (17, geometry::STGeomFromText('POLYGON((0 0 1, 4 0 2, 4 4 3, 0 4 4, 0 0 1))', 0));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeomTableTemp (ID, GeomColumn) VALUES (18, geometry::STGeomFromText('MULTILINESTRING((0 0 0, 3 0 5), (10 10 0, 10 13 5))', 0));
~~ERROR (Code: 33557097)~~

~~ERROR (Message: MULTILINESTRING is not supported)~~


CREATE TABLE TestGeospatialMethods_GeogTableTemp ( ID INT PRIMARY KEY, GeogColumn geography );
INSERT INTO TestGeospatialMethods_GeogTableTemp (ID, GeogColumn) VALUES (1, geography::STGeomFromText('LINESTRING(-122.34900 47.65100, -122.34950 47.65150)', 4326));
~~ROW COUNT: 1~~

INSERT INTO TestGeospatialMethods_GeogTableTemp (ID, GeogColumn) VALUES (2, geography::STGeomFromText('LINESTRING(-122.34900 47.65100, -122.34950 47.65150)', 0));
~~ERROR (Code: 33557097)~~

~~ERROR (Message: Invalid SRID)~~

INSERT INTO TestGeospatialMethods_GeogTableTemp (ID, GeogColumn) VALUES (3, geography::STGeomFromText('LINESTRING EMPTY', 4326));
~~ROW COUNT: 1~~


CREATE VIEW TestGeospatialMethods_lengthTemp AS SELECT CAST(GeomColumn.STLength() AS numeric(20, 6)) AS Length FROM TestGeospatialMethods_GeomTableTemp ORDER BY ID;

CREATE VIEW TestGeospatialMethods_lengthGeogTemp AS SELECT CAST(GeogColumn.STLength() AS numeric(20, 6)) AS Length FROM TestGeospatialMethods_GeogTableTemp ORDER BY ID;
Loading
Loading