HHH-15047 Ensure spatial functions have non-null return type resolver

This commit is contained in:
Karel Maesen 2022-01-23 15:49:05 +01:00
parent 6590727698
commit 610446270e
7 changed files with 127 additions and 31 deletions

View File

@ -36,7 +36,7 @@ public class BaseSqmFunctionDescriptors implements KeyedSqmFunctionDescriptors {
for ( CommonSpatialFunction func : filter( CommonSpatialFunction.values() ) ) {
final FunctionReturnTypeResolver returnTypeResolver;
if ( func.getReturnType() == null ) {
returnTypeResolver = null;
returnTypeResolver = StandardFunctionReturnTypeResolvers.useFirstNonNull();
}
else {
returnTypeResolver = StandardFunctionReturnTypeResolvers.invariant(

View File

@ -65,7 +65,7 @@ public class OracleSDOFunctionDescriptors implements KeyedSqmFunctionDescriptors
"SDO_GEOM.SDO_MBR",
true,
StandardArgumentsValidators.exactly( 1 ),
null
StandardFunctionReturnTypeResolvers.useFirstNonNull()
)
);
@ -125,7 +125,7 @@ public class OracleSDOFunctionDescriptors implements KeyedSqmFunctionDescriptors
"ST_BOUNDARY",
"ST_BOUNDARY",
1,
null,
StandardFunctionReturnTypeResolvers.useFirstNonNull(),
true
)
);
@ -196,7 +196,7 @@ public class OracleSDOFunctionDescriptors implements KeyedSqmFunctionDescriptors
"SDO_GEOM.SDO_BUFFER",
true,
StandardArgumentsValidators.exactly( 2 ),
null
StandardFunctionReturnTypeResolvers.useFirstNonNull()
)
);
@ -206,7 +206,7 @@ public class OracleSDOFunctionDescriptors implements KeyedSqmFunctionDescriptors
"SDO_GEOM.SDO_CONVEXHULL",
true,
StandardArgumentsValidators.exactly( 1 ),
null
StandardFunctionReturnTypeResolvers.useFirstNonNull()
)
);
@ -216,7 +216,7 @@ public class OracleSDOFunctionDescriptors implements KeyedSqmFunctionDescriptors
"SDO_GEOM.SDO_DIFFERENCE",
true,
StandardArgumentsValidators.exactly( 2 ),
null
StandardFunctionReturnTypeResolvers.useFirstNonNull()
)
);
@ -226,7 +226,7 @@ public class OracleSDOFunctionDescriptors implements KeyedSqmFunctionDescriptors
"SDO_GEOM.SDO_INTERSECTION",
true,
StandardArgumentsValidators.exactly( 2 ),
null
StandardFunctionReturnTypeResolvers.useFirstNonNull()
)
);
@ -236,7 +236,7 @@ public class OracleSDOFunctionDescriptors implements KeyedSqmFunctionDescriptors
"SDO_GEOM.SDO_XOR",
true,
StandardArgumentsValidators.exactly( 2 ),
null
StandardFunctionReturnTypeResolvers.useFirstNonNull()
)
);
@ -246,7 +246,7 @@ public class OracleSDOFunctionDescriptors implements KeyedSqmFunctionDescriptors
"SDO_GEOM.SDO_UNION",
true,
StandardArgumentsValidators.exactly( 2 ),
null
StandardFunctionReturnTypeResolvers.useFirstNonNull()
)
);

View File

@ -9,14 +9,11 @@ package org.hibernate.spatial.dialect.oracle;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.query.sqm.function.NamedSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.spatial.CommonSpatialFunction;
import org.hibernate.spatial.FunctionKey;
@ -52,7 +49,7 @@ public class OracleSQLMMFunctionDescriptors implements KeyedSqmFunctionDescripto
addSTFunction( CommonSpatialFunction.ST_WITHIN, StandardBasicTypes.BOOLEAN );
addSTFunction( CommonSpatialFunction.ST_EQUALS, StandardBasicTypes.BOOLEAN );
addSTFunction( CommonSpatialFunction.ST_DISTANCE, StandardBasicTypes.DOUBLE );
addSTFunction( CommonSpatialFunction.ST_RELATE, new STRelateFunction( typeRegistry ) );
addSTRelateFunction();
addSTFunction( CommonSpatialFunction.ST_DIFFERENCE );
addSTFunction( CommonSpatialFunction.ST_INTERSECTION );
addSTFunction( CommonSpatialFunction.ST_SYMDIFFERENCE );
@ -78,7 +75,13 @@ public class OracleSQLMMFunctionDescriptors implements KeyedSqmFunctionDescripto
private void addSTFunction(CommonSpatialFunction func, String stMethod) {
map.put(
func.getKey(),
new OracleSpatialSQLMMFunction( func.getKey().getName(), stMethod, func.getNumArgs(), null, true )
new OracleSpatialSQLMMFunction(
func.getKey().getName(),
stMethod,
func.getNumArgs(),
StandardFunctionReturnTypeResolvers.useFirstNonNull(),
true
)
);
}
@ -90,12 +93,11 @@ public class OracleSQLMMFunctionDescriptors implements KeyedSqmFunctionDescripto
addSTFunction( func, func.getKey().getName().toUpperCase( Locale.ROOT ) );
}
private void addSTFunction(CommonSpatialFunction func, OracleSpatialFunction descriptor) {
map.put( func.getKey(), descriptor );
private void addSTRelateFunction() {
map.put( CommonSpatialFunction.ST_RELATE.getKey(), new STRelateFunction( typeRegistry ) );
}
@Override
public Map<FunctionKey, SqmFunctionDescriptor> asMap() {
return Collections.unmodifiableMap( map );

View File

@ -0,0 +1,97 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.integration.functions;
import java.util.List;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.query.Query;
import org.hibernate.spatial.testing.SpatialTestBase;
import org.hibernate.spatial.testing.datareader.TestSupport;
import org.hibernate.spatial.testing.domain.GeomEntity;
import org.hibernate.spatial.testing.domain.JtsGeomEntity;
import org.hibernate.spatial.testing.domain.SpatialDomainModel;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.RequiresDialect;
import org.hibernate.testing.orm.junit.RequiresDialects;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
@DomainModel(modelDescriptorClasses = SpatialDomainModel.class)
@SessionFactory
@RequiresDialects({
@RequiresDialect(PostgreSQLDialect.class),
@RequiresDialect(H2Dialect.class)
})
public class BasicFunctionTest extends SpatialTestBase {
@Test
public void testJTS() {
scope.inTransaction( (session) -> {
Query<?> query = session.createQuery(
"select st_convexhull(geom) from JtsGeomEntity",
org.locationtech.jts.geom.Geometry.class
);
List<?> results = query.getResultList();
assertFalse( results.isEmpty() );
assertInstanceOf( org.locationtech.jts.geom.Geometry.class, results.get( 0 ) );
} );
}
@Override
public TestSupport.TestDataPurpose purpose() {
return TestSupport.TestDataPurpose.SpatialFunctionsData;
}
@Test
public void testGeolatte() {
scope.inTransaction( (session) -> {
Query<?> query = session.createQuery(
"select st_convexhull(e.geom) from GeomEntity e",
org.geolatte.geom.Geometry.class
);
List<?> results = query.getResultList();
assertFalse( results.isEmpty() );
assertInstanceOf( org.geolatte.geom.Geometry.class, results.get( 0 ) );
} );
}
@Test
public void testJtsIntersectsParam() {
scope.inTransaction( (session) -> {
Query<JtsGeomEntity> query = session.createQuery(
"select g from JtsGeomEntity g where st_intersects(g.geom, st_boundary(:poly) ) = true",
JtsGeomEntity.class
);
query.setParameter( "poly", org.geolatte.geom.jts.JTS.to( filterGeometry ) );
List<?> results = query.getResultList();
assertFalse( results.isEmpty() );
} );
}
@Test
public void testGeolatteIntersectsParam() {
scope.inTransaction( (session) -> {
Query<GeomEntity> query = session.createQuery(
"select g from GeomEntity g where st_intersects(g.geom, st_boundary(:poly) ) = true",
GeomEntity.class
);
query.setParameter( "poly", filterGeometry );
List<?> results = query.getResultList();
assertFalse( results.isEmpty() );
} );
}
}

View File

@ -17,7 +17,7 @@ import java.util.Objects;
public interface RowObjectMapper<T> {
default Data apply(Object obj) {
Object[] row = (Object[]) obj;
return new Data( (Number) row[0], (T) row[1] );
return new Data( (Number) row[0], row[1] );
}
}
@ -64,6 +64,7 @@ class Data {
return "Data{" +
"id=" + id +
", datum=" + datum +
" (" + datum.getClass().getCanonicalName() + ")" +
'}';
}
}

View File

@ -26,7 +26,6 @@ import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.function.Executable;
@RequiresDialectFeature(feature = IsSupportedBySpatial.class)
@SessionFactory
public class TestGeometryConstructionWithParameter extends SpatialTestBase {
@ -61,8 +60,8 @@ public class TestGeometryConstructionWithParameter extends SpatialTestBase {
@TestFactory
public Stream<DynamicTest> testFunctions() {
return Arrays.stream( CommonSpatialFunction.values() )
.filter( f -> f.getType() == CommonSpatialFunction.Type.CONSTRUCTION && isSupported( f ) && templateAvailable(
f ) )
.filter( f -> f.getType() == CommonSpatialFunction.Type.CONSTRUCTION && isSupported( f )
&& templateAvailable( f ) )
.map( this::buildTestFunction );
}
@ -72,14 +71,12 @@ public class TestGeometryConstructionWithParameter extends SpatialTestBase {
}
private Executable buildExec(final CommonSpatialFunction func) {
return () -> {
scope.inSession( session -> {
String hql = templates.get( func );
hql = adaptToDialect( session, hql );
session.createQuery( hql, GeomEntity.class ).setParameter( "poly", filterGeometry ).getResultList();
//we just check that this parses for now.
} );
};
return () -> scope.inSession( session -> {
String hql = templates.get( func );
hql = adaptToDialect( session, hql );
session.createQuery( hql, GeomEntity.class ).setParameter( "poly", filterGeometry ).getResultList();
//we just check that this parses for now.
} );
}
private String adaptToDialect(SessionImplementor session, String hql) {
@ -96,6 +93,6 @@ public class TestGeometryConstructionWithParameter extends SpatialTestBase {
}
private boolean templateAvailable(CommonSpatialFunction f) {
return templates.keySet().contains( f );
return templates.containsKey( f );
}
}

View File

@ -37,7 +37,6 @@ import static org.geolatte.geom.crs.CoordinateReferenceSystems.WGS84;
* @author Karel Maesen, Geovise BVBA
* creation-date: Sep 30, 2010
*/
@Deprecated
public abstract class TestSupport {
//TODO -- make this abstract