HHH-15160 - Properly validate the arguments in the distance operators.

This commit is contained in:
Karel Maesen 2023-04-27 21:40:36 +02:00 committed by Christian Beikov
parent 559fbe77ce
commit 174a9a7005
3 changed files with 42 additions and 6 deletions

View File

@ -119,7 +119,7 @@ Postgresql::
The Postgresql dialect has support for the https://postgis.net/[Postgis spatial extension], but not the Geometric types mentioned in the
https://www.postgresql.org/docs/current/datatype-geometric.html[Postgresql documentation].
In addition tot he common spatial functions, the following functions are supported:
In addition to the common spatial functions, the following functions are supported:
.Additional Postgis function support

View File

@ -11,8 +11,10 @@ import java.util.List;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.query.sqm.function.NamedSqmFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.spatial.BaseSqmFunctionDescriptors;
import org.hibernate.spatial.FunctionKey;
@ -24,7 +26,7 @@ import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.StandardBasicTypes;
import static org.hibernate.query.sqm.produce.function.StandardArgumentsValidators.exactly;
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.SPATIAL;
public class PostgisSqmFunctionDescriptors extends BaseSqmFunctionDescriptors {
@ -47,7 +49,7 @@ public class PostgisSqmFunctionDescriptors extends BaseSqmFunctionDescriptors {
new PostgisOperator(
name,
operator,
exactly( 2 ),
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 2 ), SPATIAL ),
StandardFunctionReturnTypeResolvers.invariant( typeRegistry.resolve(
StandardBasicTypes.DOUBLE )
)

View File

@ -33,7 +33,9 @@ import org.geolatte.geom.crs.CoordinateReferenceSystems;
import static org.geolatte.geom.builder.DSL.c;
import static org.geolatte.geom.builder.DSL.point;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
@ -73,7 +75,7 @@ public class PostgisDistanceOperatorsTest {
List<Neighbor> results = query.getResultList();
assertFalse( results.isEmpty() );
String sql = inspector.getSqlQueries().get( 0 );
assertTrue(sql.matches(".*order by.*point\\w*<->.*"), "<-> operator is not rendered correctly");
assertTrue( sql.matches( ".*order by.*point\\w*<->.*" ), "<-> operator is not rendered correctly" );
}
);
}
@ -90,7 +92,7 @@ public class PostgisDistanceOperatorsTest {
List<Neighbor> results = query.getResultList();
assertFalse( results.isEmpty() );
String sql = inspector.getSqlQueries().get( 0 );
assertTrue(sql.matches(".*order by.*point\\w*<#>.*"), "<#> operator is not rendered correctly");
assertTrue( sql.matches( ".*order by.*point\\w*<#>.*" ), "<#> operator is not rendered correctly" );
}
);
}
@ -107,11 +109,43 @@ public class PostgisDistanceOperatorsTest {
List<Neighbor> results = query.getResultList();
assertFalse( results.isEmpty() );
String sql = inspector.getSqlQueries().get( 0 );
assertTrue(sql.matches(".*order by.*point\\w*<<->>.*"), "<<->>> operator is not rendered correctly");
assertTrue(
sql.matches( ".*order by.*point\\w*<<->>.*" ),
"<<->>> operator is not rendered correctly"
);
}
);
}
@Test
public void testInvalidArguments(SessionFactoryScope scope) {
SQLStatementInspector inspector = scope.getCollectingStatementInspector();
inspector.clear();
IllegalArgumentException thrown = assertThrows( IllegalArgumentException.class, () ->
scope.inTransaction(
session -> {
TypedQuery<Neighbor> query = session.createQuery(
"select n from Neighbor n order by distance_2d_bbox(n.point, :pnt )",
Neighbor.class
)
.setParameter( "pnt", 130 );
List<Neighbor> results = query.getResultList();
assertFalse( results.isEmpty() );
String sql = inspector.getSqlQueries().get( 0 );
assertTrue(
sql.matches( ".*order by.*point\\w*<#>.*" ),
"<#> operator is not rendered correctly"
);
}
)
);
assertEquals(
"Parameter 1 of function distance_2d_bbox() has type SPATIAL, but argument is of type java.lang.Integer",
thrown.getMessage()
);
}
@AfterEach
public void cleanUp(SessionFactoryScope scope) {
scope.inTransaction(