HHH-12798: Fix for nested spatial functions on SAP HANA

This commit is contained in:
Jonathan Bregler 2018-07-12 12:32:16 +02:00 committed by Vlad Mihalcea
parent a9d5847fa9
commit dfe0bcbbca
3 changed files with 115 additions and 53 deletions

View File

@ -57,50 +57,44 @@ public class HANASpatialFunction extends StandardSQLFunction {
if ( arguments.size() == 0 ) {
return getName() + "()";
}
else {
final StringBuilder buf = new StringBuilder();
int firstArgumentIndex;
if ( staticFunction ) {
// Add function call
buf.append( getName() );
firstArgumentIndex = 0;
}
else {
// If the first argument is an expression, e.g. a nested function, strip the .ST_AsEWKB() suffix
buf.append( stripEWKBSuffix( arguments.get( 0 ) ) );
// Add function call
buf.append( "." ).append( getName() );
firstArgumentIndex = 1;
}
buf.append( '(' );
// Add function arguments
for ( int i = firstArgumentIndex; i < arguments.size(); i++ ) {
final Object argument = arguments.get( i );
// Check if first argument needs to be parsed from EWKB. This is the case if the first argument is a
// parameter that is set as EWKB or if it's a nested function call.
final boolean parseFromWKB = ( isGeometryArgument( i ) && "?".equals( argument ) );
if ( parseFromWKB ) {
buf.append( "ST_GeomFromEWKB(" );
}
buf.append( stripEWKBSuffix( argument ) );
if ( parseFromWKB ) {
buf.append( ")" );
}
if ( i < arguments.size() - 1 ) {
buf.append( ", " );
}
}
buf.append( ')' );
// If it doesn't specify an explicit type, assume it's a geometry
if ( this.getType() == null ) {
buf.append( AS_EWKB_SUFFIX );
}
return buf.toString();
final StringBuilder buf = new StringBuilder();
int firstArgumentIndex;
if ( this.staticFunction ) {
// Add function call
buf.append( getName() );
firstArgumentIndex = 0;
}
else {
// If the first argument is an expression, e.g. a nested function, strip the .ST_AsEWKB() suffix
Object argument = arguments.get( 0 );
final boolean parseFromWKB = ( "?".equals( argument ) );
appendArgument( argument, parseFromWKB, buf );
// Add function call
buf.append( "." ).append( getName() );
firstArgumentIndex = 1;
}
buf.append( '(' );
// Add function arguments
for ( int i = firstArgumentIndex; i < arguments.size(); i++ ) {
final Object argument = arguments.get( i );
// Check if first argument needs to be parsed from EWKB. This is the case if the first argument is a
// parameter that is set as EWKB or if it's a nested function call.
final boolean parseFromWKB = ( isGeometryArgument( i ) && "?".equals( argument ) );
appendArgument( argument, parseFromWKB, buf );
if ( i < arguments.size() - 1 ) {
buf.append( ", " );
}
}
buf.append( ')' );
// If it doesn't specify an explicit type, assume it's a geometry
if ( this.getType() == null ) {
buf.append( AS_EWKB_SUFFIX );
}
return buf.toString();
}
private Object stripEWKBSuffix(Object argument) {
@ -115,4 +109,14 @@ public class HANASpatialFunction extends StandardSQLFunction {
private boolean isGeometryArgument(int idx) {
return this.argumentIsGeometryTypeMask.size() > idx && this.argumentIsGeometryTypeMask.get( idx );
}
private void appendArgument(Object argument, boolean parseFromWKB, StringBuilder buf) {
if ( parseFromWKB ) {
buf.append( "ST_GeomFromEWKB(" );
}
buf.append( stripEWKBSuffix( argument ) );
if ( parseFromWKB ) {
buf.append( ")" );
}
}
}

View File

@ -1018,6 +1018,31 @@ public class TestHANASpatialFunctions extends TestSpatialFunctions {
retrieveHQLResultsAndCompare( dbexpected, hql, pckg );
}
@Test
public void test_nestedfunction_on_jts() throws SQLException {
nestedfunction( JTS );
}
@Test
public void test_nestedfunction_on_geolatte() throws SQLException {
nestedfunction( GEOLATTE );
}
public void nestedfunction(String pckg) throws SQLException {
Map<Integer, Geometry> dbexpected = hanaExpectationsFactory.getNestedFunctionInner( expectationsFactory.getTestPolygon() );
String hql = format(
"SELECT id, geom FROM org.hibernate.spatial.integration.%s.GeomEntity g where dwithin(geom, srid(:filter, 0), 1) = true",
pckg );
Map<String, Object> params = createQueryParams( "filter", expectationsFactory.getTestPolygon() );
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
dbexpected = hanaExpectationsFactory.getNestedFunctionOuter( expectationsFactory.getTestPolygon() );
hql = format(
"SELECT id, geom FROM org.hibernate.spatial.integration.%s.GeomEntity g where dwithin(:filter, srid(geom, 0), 1) = true",
pckg );
retrieveHQLResultsAndCompare( dbexpected, hql, params, pckg );
}
private String getGeometryTypeFromPackage(String pckg) {
switch ( pckg ) {
case GEOLATTE:

View File

@ -1097,4 +1097,37 @@ public class HANAExpectationsFactory extends AbstractExpectationsFactory {
"select t.id, t.geom.ST_ZMin() from GeomTest t where t.geom.ST_SRID() = "
+ getTestSrid() );
}
/**
* Returns the result of a nested function call with a parameter inside the inner function
*
* @return map of identifier, geometry
* @throws SQLException
*/
public Map<Integer, Geometry> getNestedFunctionInner(Geometry geom) throws SQLException {
return retrieveExpected( createNativeNestedFunctionInnerStatement( geom ), GEOMETRY );
}
private NativeSQLStatement createNativeNestedFunctionInnerStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, t.geom from GeomTest t where t.geom.ST_WithinDistance(ST_GeomFromText(?, " + getTestSrid()
+ ").ST_SRID(0), 1) = 1",
geom.toText() );
}
/**
* Returns the result of a nested function call with a parameter inside the outer function
*
* @return map of identifier, geometry
* @throws SQLException
*/
public Map<Integer, Geometry> getNestedFunctionOuter(Geometry geom) throws SQLException {
return retrieveExpected( createNativeNestedFunctionOuterStatement( geom ), GEOMETRY );
}
private NativeSQLStatement createNativeNestedFunctionOuterStatement(Geometry geom) {
return createNativeSQLStatementAllWKTParams(
"select t.id, t.geom from GeomTest t where ST_GeomFromText(?, " + getTestSrid() + ").ST_WithinDistance(geom.ST_SRID(0), 1) = 1",
geom.toText() );
}
}