Properly handle SQLFunction registrations

This commit is contained in:
Christian Beikov 2021-10-11 13:32:11 +02:00
parent 6ddf3530fa
commit 4f861e13ba
2 changed files with 39 additions and 2 deletions

View File

@ -6,8 +6,17 @@
*/
package org.hibernate.dialect.function;
import java.util.List;
import java.util.function.Supplier;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.sqm.function.NamedSqmFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.type.BasicTypeReference;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Simplified API allowing users to contribute
@ -28,7 +37,20 @@ public class StandardSQLFunction extends NamedSqmFunctionDescriptor {
}
public StandardSQLFunction(String name, boolean useParentheses, BasicTypeReference<?> type) {
super( name, useParentheses, null, null );
super( name, useParentheses, null, new FunctionReturnTypeResolver() {
@Override
public AllowableFunctionReturnType<?> resolveFunctionReturnType(
AllowableFunctionReturnType<?> impliedType,
List<? extends SqmTypedNode<?>> arguments,
TypeConfiguration typeConfiguration) {
return type == null ? null : typeConfiguration.getBasicTypeRegistry().resolve( type );
}
@Override
public BasicValuedMapping resolveFunctionReturnType(Supplier<BasicValuedMapping> impliedTypeAccess, List<? extends SqlAstNode> arguments) {
return type == null || impliedTypeAccess == null ? null : impliedTypeAccess.get();
}
} );
this.type = type;
}

View File

@ -34,6 +34,7 @@ import org.hibernate.query.internal.QueryInterpretationCacheDisabledImpl;
import org.hibernate.query.internal.QueryInterpretationCacheStandardImpl;
import org.hibernate.query.named.NamedObjectRepository;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.query.sqm.internal.SqmCreationOptionsStandard;
import org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder;
@ -72,6 +73,20 @@ public class QueryEngine {
);
final SqmTranslatorFactory sqmTranslatorFactory = resolveSqmTranslatorFactory( queryEngineOptions, dialect );
final SqmFunctionRegistry customSqmFunctionRegistry;
if ( queryEngineOptions.getCustomSqmFunctionRegistry() == null ) {
final Map<String, SqmFunctionDescriptor> customSqlFunctionMap = queryEngineOptions.getCustomSqlFunctionMap();
if ( customSqlFunctionMap == null || customSqlFunctionMap.isEmpty() ) {
customSqmFunctionRegistry = null;
}
else {
customSqmFunctionRegistry = new SqmFunctionRegistry();
customSqlFunctionMap.forEach( customSqmFunctionRegistry::register );
}
}
else {
customSqmFunctionRegistry = queryEngineOptions.getCustomSqmFunctionRegistry();
}
return new QueryEngine(
sessionFactory.getUuid(),
@ -86,7 +101,7 @@ public class QueryEngine {
buildInterpretationCache( sessionFactory::getStatistics, sessionFactory.getProperties() ),
metadata.getTypeConfiguration(),
dialect,
queryEngineOptions.getCustomSqmFunctionRegistry(),
customSqmFunctionRegistry,
sessionFactory.getServiceRegistry()
);
}