HHH-17677 handle literal null arguments more elegantly in StandardFunctionReturnTypeResolvers
resolves a very confusing error message
This commit is contained in:
parent
e90dba2c98
commit
78990a7910
|
@ -12,16 +12,15 @@ import java.util.Locale;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
import org.hibernate.Internal;
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
import org.hibernate.query.sqm.tree.expression.NullSqmExpressible;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.type.BasicType;
|
||||
|
@ -252,7 +251,10 @@ public class StandardFunctionReturnTypeResolvers {
|
|||
int position) {
|
||||
final SqmTypedNode<?> specifiedArgument = arguments.get( position - 1 );
|
||||
final SqmExpressible<?> specifiedArgType = getArgumentExpressible( specifiedArgument );
|
||||
if ( specifiedArgType != null && !(specifiedArgType instanceof ReturnableType ) ) {
|
||||
if ( specifiedArgType == null || specifiedArgType instanceof NullSqmExpressible ) {
|
||||
return null;
|
||||
}
|
||||
else if ( !(specifiedArgType instanceof ReturnableType) ) {
|
||||
throw new FunctionArgumentException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
|
@ -263,8 +265,9 @@ public class StandardFunctionReturnTypeResolvers {
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (ReturnableType<?>) specifiedArgType;
|
||||
else {
|
||||
return (ReturnableType<?>) specifiedArgType;
|
||||
}
|
||||
}
|
||||
|
||||
private static SqmExpressible<?> getArgumentExpressible(SqmTypedNode<?> specifiedArgument) {
|
||||
|
@ -272,9 +275,9 @@ public class StandardFunctionReturnTypeResolvers {
|
|||
final SqmExpressible<?> specifiedArgType = expressible instanceof SqmTypedNode<?>
|
||||
? ( (SqmTypedNode<?>) expressible ).getNodeType()
|
||||
: expressible;
|
||||
return specifiedArgType instanceof SqmPathSource ?
|
||||
( (SqmPathSource<?>) specifiedArgType ).getSqmPathType() :
|
||||
specifiedArgType;
|
||||
return specifiedArgType instanceof SqmPathSource
|
||||
? ( (SqmPathSource<?>) specifiedArgType ).getSqmPathType()
|
||||
: specifiedArgType;
|
||||
}
|
||||
|
||||
public static JdbcMapping extractArgumentJdbcMapping(
|
||||
|
|
|
@ -11,7 +11,6 @@ import java.util.Objects;
|
|||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.metamodel.mapping.SqlExpressible;
|
||||
import org.hibernate.sql.ast.SqlAstWalker;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionAccess;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
|
@ -93,7 +92,10 @@ public class SqlSelectionImpl implements SqlSelection, SqlExpressionAccess {
|
|||
}
|
||||
|
||||
private static ValueExtractor determineValueExtractor(Expression sqlExpression, JavaType<?> jdbcJavaType) {
|
||||
final JdbcMapping jdbcMapping = sqlExpression.getExpressionType().getSingleJdbcMapping();
|
||||
final JdbcMappingContainer expressionType = sqlExpression.getExpressionType();
|
||||
final JdbcMapping jdbcMapping = expressionType == null
|
||||
? JavaObjectType.INSTANCE
|
||||
: expressionType.getSingleJdbcMapping();
|
||||
if ( jdbcJavaType == null || jdbcMapping.getMappedJavaType() == jdbcJavaType ) {
|
||||
return jdbcMapping.getJdbcValueExtractor();
|
||||
}
|
||||
|
@ -102,6 +104,7 @@ public class SqlSelectionImpl implements SqlSelection, SqlExpressionAccess {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Expression getExpression() {
|
||||
return sqlExpression;
|
||||
|
|
|
@ -2248,4 +2248,22 @@ public class FunctionTests {
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SkipForDialect(dialectClass = H2Dialect.class)
|
||||
@SkipForDialect(dialectClass = DerbyDialect.class)
|
||||
@SkipForDialect(dialectClass = HSQLDialect.class)
|
||||
@SkipForDialect(dialectClass = DB2Dialect.class)
|
||||
public void testNullInCoalesce(SessionFactoryScope scope) {
|
||||
scope.inTransaction(s -> {
|
||||
assertEquals("hello",
|
||||
s.createQuery("select coalesce(null, :word)", String.class)
|
||||
.setParameter("word", "hello")
|
||||
.getSingleResultOrNull());
|
||||
assertEquals("hello",
|
||||
s.createQuery("select coalesce(:word, null)", String.class)
|
||||
.setParameter("word", "hello")
|
||||
.getSingleResultOrNull());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue