diff --git a/NHibernate.Spatial.PostGis/Dialect/PostGisDialect.cs b/NHibernate.Spatial.PostGis/Dialect/PostGisDialect.cs index 1e14001e..88f97b4e 100644 --- a/NHibernate.Spatial.PostGis/Dialect/PostGisDialect.cs +++ b/NHibernate.Spatial.PostGis/Dialect/PostGisDialect.cs @@ -445,9 +445,32 @@ protected string GetSpatialCreateString(string schema, string prefix) { // Intersection aggregate function by Mark Fenbers // See http://postgis.refractions.net/pipermail/postgis-users/2005-May/008156.html - string script = string.Format( - "DROP AGGREGATE IF EXISTS {0}{1}(GEOMETRY);" + - "CREATE AGGREGATE {0}{1}(BASETYPE=GEOMETRY, SFUNC={2}Intersection, STYPE=GEOMETRY);" + // NOTE: An additional paramter was added to ST_Intersection in PostGIS 3.1 + // https://github.com/nhibernate/NHibernate.Spatial/issues/129 + string script = string.Format(@" + CREATE OR REPLACE FUNCTION {0}NHSP_CreateIntersectionAggregate() + RETURNS void AS $$ + BEGIN + DROP AGGREGATE IF EXISTS {0}{1}(GEOMETRY); + IF (SELECT PostGIS_Lib_Version() < '3.1') THEN + CREATE AGGREGATE {0}{1}(basetype=geometry, sfunc={2}Intersection, stype=geometry); + ELSE + CREATE OR REPLACE FUNCTION {0}NHSP_Intersection(geometry, geometry) + RETURNS geometry + LANGUAGE SQL + AS 'SELECT {0}{2}Intersection($1, $2)' + IMMUTABLE STRICT + COST 10000; + CREATE AGGREGATE {0}{1}(basetype=geometry, sfunc={0}NHSP_Intersection, stype=geometry); + END IF; + END; + $$ LANGUAGE plpgsql; + + -- NOTE: Cast to text required to avoid following error on PostgreSQL 9.0 and lower: + -- Npgsql.PostgresException : 42883: no binary output function available for type void + -- https://github.com/npgsql/npgsql/issues/818 + -- https://www.postgresql.org/message-id/21459.1437692282%40sss.pgh.pa.us + SELECT {0}NHSP_CreateIntersectionAggregate()::text;" , this.QuoteSchema(schema) , IntersectionAggregateName , prefix diff --git a/Tests.NHibernate.Spatial.PostGis/PostGisConformanceItemsFixture.cs b/Tests.NHibernate.Spatial.PostGis/PostGisConformanceItemsFixture.cs index 3ed05a85..dc979eeb 100644 --- a/Tests.NHibernate.Spatial.PostGis/PostGisConformanceItemsFixture.cs +++ b/Tests.NHibernate.Spatial.PostGis/PostGisConformanceItemsFixture.cs @@ -66,40 +66,5 @@ public override void ConformanceItemT31Linq() Assert.IsTrue(expected.EqualsTopologically(geometry)); } - - /// - /// Overridden because polygon vertices are returned in a different order in PostGIS - /// - [Test] - public override void ConformanceItemT48Hql() - { - string query = - @"select NHSP.AsText(NHSP.Difference(np.Boundary, f.Boundary)) - from NamedPlace np, Forest f - where np.Name = 'Ashton' and f.Name = 'Green Forest' - "; - string result = session.CreateQuery(query) - .UniqueResult(); - - Geometry geometry = Wkt.Read(result); - Geometry expected = Wkt.Read("POLYGON ((62 48, 84 48, 84 42, 56 34, 62 48))"); - - Assert.IsTrue(expected.EqualsExact(geometry, Tolerance)); - } - - [Test] - public override void ConformanceItemT48Linq() - { - var query = - from np in session.Query() - from f in session.Query() - where np.Name == "Ashton" && f.Name == "Green Forest" - select np.Boundary.Difference(f.Boundary); - - Geometry geometry = query.Single(); - Geometry expected = Wkt.Read("POLYGON ((62 48, 84 48, 84 42, 56 34, 62 48))"); - - Assert.IsTrue(expected.EqualsExact(geometry, Tolerance)); - } } } diff --git a/Tests.NHibernate.Spatial/OgcSfSql11Compliance/ConformanceItemsFixture.cs b/Tests.NHibernate.Spatial/OgcSfSql11Compliance/ConformanceItemsFixture.cs index b9689f52..1889a33f 100644 --- a/Tests.NHibernate.Spatial/OgcSfSql11Compliance/ConformanceItemsFixture.cs +++ b/Tests.NHibernate.Spatial/OgcSfSql11Compliance/ConformanceItemsFixture.cs @@ -2556,7 +2556,7 @@ public virtual void ConformanceItemT48Hql() Geometry geometry = Wkt.Read(result); Geometry expected = Wkt.Read("POLYGON( ( 56 34, 62 48, 84 48, 84 42, 56 34) )"); - Assert.IsTrue(expected.EqualsExact(geometry, Tolerance)); + Assert.IsTrue(expected.EqualsTopologically(geometry)); } [Test] @@ -2571,7 +2571,7 @@ public virtual void ConformanceItemT48Linq() Geometry geometry = query.Single(); Geometry expected = Wkt.Read("POLYGON( ( 56 34, 62 48, 84 48, 84 42, 56 34) )"); - Assert.IsTrue(expected.EqualsExact(geometry, Tolerance)); + Assert.IsTrue(expected.EqualsTopologically(geometry)); } ///