resolve an issue with ArgumentsValidator and access to the MappingMetamodel
(ideally we should never access the MappingMetamodel from ArgumentsValidator)
This commit is contained in:
parent
e3ed3028c4
commit
196d7a1b5a
|
@ -6,20 +6,19 @@
|
|||
*/
|
||||
package org.hibernate.community.dialect;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.engine.query.internal.NativeQueryInterpreterStandardImpl;
|
||||
import org.hibernate.metamodel.model.domain.internal.JpaMetamodelImpl;
|
||||
import org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl;
|
||||
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||
import org.hibernate.query.criteria.ValueHandlingMode;
|
||||
import org.hibernate.query.internal.NamedObjectRepositoryImpl;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.spi.StringBuilderSqlAppender;
|
||||
import org.hibernate.testing.boot.MetadataBuildingContextTestingImpl;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.descriptor.java.JdbcDateJavaType;
|
||||
import org.hibernate.type.descriptor.java.JdbcTimestampJavaType;
|
||||
|
@ -33,6 +32,9 @@ import org.junit.AfterClass;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static org.hibernate.engine.query.internal.NativeQueryInterpreterStandardImpl.NATIVE_QUERY_INTERPRETER;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
|
@ -43,15 +45,18 @@ import static org.junit.Assert.assertEquals;
|
|||
public class InformixDialectTestCase extends BaseUnitTestCase {
|
||||
|
||||
private static final InformixDialect dialect = new InformixDialect();
|
||||
private static ServiceRegistry ssr;
|
||||
private static StandardServiceRegistry ssr;
|
||||
private static QueryEngine queryEngine;
|
||||
private static MappingMetamodelImplementor mappingMetamodel;
|
||||
private static TypeConfiguration typeConfiguration;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
TypeConfiguration typeConfiguration = new TypeConfiguration();
|
||||
final JpaMetamodelImpl jpaMetamodel = new JpaMetamodelImpl( typeConfiguration, new MappingMetamodelImpl( typeConfiguration, ssr ), ssr );
|
||||
|
||||
ssr = new StandardServiceRegistryBuilder().build();
|
||||
typeConfiguration = new TypeConfiguration();
|
||||
typeConfiguration.scope( new MetadataBuildingContextTestingImpl( ssr ) );
|
||||
mappingMetamodel = new MappingMetamodelImpl( typeConfiguration, ssr );
|
||||
final JpaMetamodelImpl jpaMetamodel = new JpaMetamodelImpl( typeConfiguration, mappingMetamodel, ssr );
|
||||
queryEngine = new QueryEngine(
|
||||
null,
|
||||
null,
|
||||
|
@ -59,8 +64,8 @@ public class InformixDialectTestCase extends BaseUnitTestCase {
|
|||
ValueHandlingMode.BIND,
|
||||
dialect.getPreferredSqlTypeCodeForBoolean(),
|
||||
false,
|
||||
new NamedObjectRepositoryImpl( Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap() ),
|
||||
NativeQueryInterpreterStandardImpl.NATIVE_QUERY_INTERPRETER,
|
||||
new NamedObjectRepositoryImpl( emptyMap(), emptyMap(), emptyMap(), emptyMap() ),
|
||||
NATIVE_QUERY_INTERPRETER,
|
||||
dialect,
|
||||
ssr
|
||||
);
|
||||
|
@ -89,17 +94,14 @@ public class InformixDialectTestCase extends BaseUnitTestCase {
|
|||
public void testCurrentTimestampFunction() {
|
||||
SqmFunctionDescriptor functionDescriptor = queryEngine.getSqmFunctionRegistry()
|
||||
.findFunctionDescriptor( "current_timestamp" );
|
||||
SelfRenderingSqmFunction<Object> sqmExpression = functionDescriptor.generateSqmExpression(
|
||||
null,
|
||||
queryEngine,
|
||||
new TypeConfiguration()
|
||||
);
|
||||
SelfRenderingSqmFunction<Object> sqmExpression =
|
||||
functionDescriptor.generateSqmExpression( null, queryEngine, typeConfiguration );
|
||||
BasicType<?> basicType = (BasicType<?>) sqmExpression.getNodeType();
|
||||
assertEquals( JdbcTimestampJavaType.INSTANCE, basicType.getJavaTypeDescriptor() );
|
||||
assertEquals( TimestampJdbcType.INSTANCE, basicType.getJdbcType() );
|
||||
|
||||
SqlAppender appender = new StringBuilderSqlAppender();
|
||||
sqmExpression.getRenderingSupport().render( appender, Collections.emptyList(), null );
|
||||
sqmExpression.getRenderingSupport().render( appender, emptyList(), null );
|
||||
assertEquals( "current", appender.toString() );
|
||||
}
|
||||
|
||||
|
@ -108,17 +110,14 @@ public class InformixDialectTestCase extends BaseUnitTestCase {
|
|||
public void testCurrentDateFunction() {
|
||||
SqmFunctionDescriptor functionDescriptor = queryEngine.getSqmFunctionRegistry()
|
||||
.findFunctionDescriptor( "current_date" );
|
||||
SelfRenderingSqmFunction<Object> sqmExpression = functionDescriptor.generateSqmExpression(
|
||||
null,
|
||||
queryEngine,
|
||||
new TypeConfiguration()
|
||||
);
|
||||
SelfRenderingSqmFunction<Object> sqmExpression =
|
||||
functionDescriptor.generateSqmExpression( null, queryEngine, typeConfiguration );
|
||||
BasicType<?> basicType = (BasicType<?>) sqmExpression.getNodeType();
|
||||
assertEquals( JdbcDateJavaType.INSTANCE, basicType.getJavaTypeDescriptor() );
|
||||
assertEquals( DateJdbcType.INSTANCE, basicType.getJdbcType() );
|
||||
|
||||
SqlAppender appender = new StringBuilderSqlAppender();
|
||||
sqmExpression.getRenderingSupport().render( appender, Collections.emptyList(), null );
|
||||
sqmExpression.getRenderingSupport().render( appender, emptyList(), null );
|
||||
assertEquals( "today", appender.toString() );
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.metamodel.MappingMetamodel;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||
|
@ -43,7 +42,7 @@ public class ChrLiteralEmulation extends AbstractSqmSelfRenderingFunctionDescrip
|
|||
StandardArgumentsValidators.exactly(1),
|
||||
new ArgumentsValidator() {
|
||||
@Override
|
||||
public void validate(List<? extends SqmTypedNode<?>> arguments, String functionName, MappingMetamodel metamodel) {
|
||||
public void validate(List<? extends SqmTypedNode<?>> arguments, String functionName, TypeConfiguration typeConfiguration) {
|
||||
if ( !( arguments.get( 0 ) instanceof SqmLiteral<?> ) ) {
|
||||
throw new QueryException(
|
||||
String.format(
|
||||
|
|
|
@ -47,10 +47,6 @@ public interface MappingMetamodel {
|
|||
Function<NavigablePath,
|
||||
TableGroup> tableGroupLocator);
|
||||
|
||||
MappingModelExpressible<?> lenientlyResolveMappingExpressible(
|
||||
SqmExpressible<?> sqmExpressible,
|
||||
Function<NavigablePath, TableGroup> tableGroupLocator);
|
||||
|
||||
/**
|
||||
* Given a Java type, determine the corresponding BindableType to
|
||||
* use implicitly
|
||||
|
@ -67,11 +63,6 @@ public interface MappingMetamodel {
|
|||
void forEachEntityDescriptor(Consumer<EntityPersister> action);
|
||||
Stream<EntityPersister> streamEntityDescriptors();
|
||||
|
||||
/**
|
||||
* Given a JPA entity domain type, get the associated Hibernate entity descriptor
|
||||
*/
|
||||
EntityPersister resolveEntityDescriptor(EntityDomainType<?> entityDomainType);
|
||||
|
||||
/**
|
||||
* Get an entity mapping descriptor based on its Hibernate entity-name
|
||||
*
|
||||
|
|
|
@ -376,11 +376,6 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo
|
|||
return entityPersisterMap.values().stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister resolveEntityDescriptor(EntityDomainType<?> entityDomainType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPersister getEntityDescriptor(String entityName) {
|
||||
final EntityPersister entityPersister = entityPersisterMap.get( entityName );
|
||||
|
@ -750,14 +745,10 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo
|
|||
}
|
||||
|
||||
@Override
|
||||
public MappingModelExpressible<?> lenientlyResolveMappingExpressible(
|
||||
public MappingModelExpressible<?> resolveMappingExpressible(
|
||||
SqmExpressible<?> sqmExpressible,
|
||||
Function<NavigablePath, TableGroup> tableGroupLocator) {
|
||||
return resolveMappingExpressible(sqmExpressible, tableGroupLocator );
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingModelExpressible<?> resolveMappingExpressible(SqmExpressible<?> sqmExpressible, Function<NavigablePath, TableGroup> tableGroupLocator) {
|
||||
Function<NavigablePath,
|
||||
TableGroup> tableGroupLocator) {
|
||||
if ( sqmExpressible instanceof SqmPath ) {
|
||||
final SqmPath<?> sqmPath = (SqmPath<?>) sqmExpressible;
|
||||
final NavigablePath navigablePath = sqmPath.getNavigablePath();
|
||||
|
|
|
@ -74,9 +74,7 @@ import jakarta.persistence.criteria.Subquery;
|
|||
public interface NodeBuilder extends HibernateCriteriaBuilder {
|
||||
JpaMetamodel getDomainModel();
|
||||
|
||||
default TypeConfiguration getTypeConfiguration() {
|
||||
return getDomainModel().getTypeConfiguration();
|
||||
}
|
||||
TypeConfiguration getTypeConfiguration();
|
||||
|
||||
boolean isJpaQueryComplianceEnabled();
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ public abstract class AbstractSqmFunctionDescriptor implements SqmFunctionDescri
|
|||
ReturnableType<T> impliedResultType,
|
||||
QueryEngine queryEngine,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
argumentsValidator.validate( arguments, getName(), queryEngine);
|
||||
argumentsValidator.validate( arguments, getName(), typeConfiguration );
|
||||
|
||||
return generateSqmFunctionExpression(
|
||||
arguments,
|
||||
|
@ -118,7 +118,7 @@ public abstract class AbstractSqmFunctionDescriptor implements SqmFunctionDescri
|
|||
ReturnableType<T> impliedResultType,
|
||||
QueryEngine queryEngine,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
argumentsValidator.validate( arguments, getName(), queryEngine );
|
||||
argumentsValidator.validate( arguments, getName(), typeConfiguration );
|
||||
|
||||
return generateSqmAggregateFunctionExpression(
|
||||
arguments,
|
||||
|
@ -137,7 +137,7 @@ public abstract class AbstractSqmFunctionDescriptor implements SqmFunctionDescri
|
|||
ReturnableType<T> impliedResultType,
|
||||
QueryEngine queryEngine,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
argumentsValidator.validate( arguments, getName(), queryEngine );
|
||||
argumentsValidator.validate( arguments, getName(), typeConfiguration );
|
||||
|
||||
return generateSqmOrderedSetAggregateFunctionExpression(
|
||||
arguments,
|
||||
|
@ -158,7 +158,7 @@ public abstract class AbstractSqmFunctionDescriptor implements SqmFunctionDescri
|
|||
ReturnableType<T> impliedResultType,
|
||||
QueryEngine queryEngine,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
argumentsValidator.validate( arguments, getName(), queryEngine );
|
||||
argumentsValidator.validate( arguments, getName(), typeConfiguration );
|
||||
|
||||
return generateSqmWindowFunctionExpression(
|
||||
arguments,
|
||||
|
@ -233,7 +233,8 @@ public abstract class AbstractSqmFunctionDescriptor implements SqmFunctionDescri
|
|||
* Return an SQM node or subtree representing an invocation of this window function
|
||||
* with the given arguments. This method may be overridden in the case of
|
||||
* function descriptors that wish to customize creation of the node.
|
||||
* @param arguments the arguments of the function invocation
|
||||
*
|
||||
* @param arguments the arguments of the function invocation
|
||||
* @param respectNulls
|
||||
* @param fromFirst
|
||||
* @param impliedResultType the function return type as inferred from its usage
|
||||
|
|
|
@ -219,6 +219,11 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
return domainModelAccess.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeConfiguration getTypeConfiguration() {
|
||||
return queryEngine.getTypeConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJpaQueryComplianceEnabled() {
|
||||
return jpaComplianceEnabled;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm.produce.function;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.metamodel.MappingMetamodel;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
|
@ -13,6 +14,7 @@ import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
|||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.ModelPartContainer;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
|
@ -29,6 +31,7 @@ import org.hibernate.type.descriptor.java.JavaType;
|
|||
import org.hibernate.type.descriptor.java.spi.JdbcTypeRecommendationException;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.sql.Types;
|
||||
|
@ -50,19 +53,30 @@ import static org.hibernate.type.SqlTypes.isTemporalType;
|
|||
|
||||
/**
|
||||
* Typechecks the arguments of HQL functions based on the assigned JDBC types.
|
||||
* The main purpose for doing this is that we want to be able to check named
|
||||
* queries at startup or build time, and we want to be able to check all queries
|
||||
* in the IDE.
|
||||
*
|
||||
* @apiNote Originally, the main purpose for doing this was that we wanted to be
|
||||
* able to check named queries at startup or build time, and we wanted
|
||||
* to be able to check all queries in the IDE. But since Hibernate 6
|
||||
* it's of more general importance.
|
||||
*
|
||||
* @implNote Access to the {@link MappingMetamodel} is very problematic here,
|
||||
* since we are sometimes called in a context where we have not built
|
||||
* a {@link org.hibernate.internal.SessionFactoryImpl}, and therefore
|
||||
* we have no persisters.
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class ArgumentTypesValidator implements ArgumentsValidator {
|
||||
// a JDBC type code of an enum when we don't know if it's mapped STRING or ORDINAL
|
||||
// this number has to be distinct from every code in SqlTypes!
|
||||
private static final int ENUM_UNKNOWN_JDBC_TYPE = -101977;
|
||||
|
||||
final ArgumentsValidator delegate;
|
||||
private final FunctionParameterType[] types;
|
||||
|
||||
public ArgumentTypesValidator(ArgumentsValidator delegate, FunctionParameterType... types) {
|
||||
this.types = types;
|
||||
if (delegate == null ) {
|
||||
if ( delegate == null ) {
|
||||
delegate = StandardArgumentsValidators.exactly(types.length);
|
||||
}
|
||||
this.delegate = delegate;
|
||||
|
@ -78,21 +92,20 @@ public class ArgumentTypesValidator implements ArgumentsValidator {
|
|||
public void validate(
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
String functionName,
|
||||
MappingMetamodel metamodel) {
|
||||
delegate.validate( arguments, functionName, metamodel );
|
||||
TypeConfiguration typeConfiguration) {
|
||||
delegate.validate( arguments, functionName, typeConfiguration);
|
||||
int count = 0;
|
||||
for (SqmTypedNode<?> argument : arguments) {
|
||||
JdbcTypeIndicators indicators = metamodel.getTypeConfiguration().getCurrentBaseSqlTypeIndicators();
|
||||
JdbcTypeIndicators indicators = typeConfiguration.getCurrentBaseSqlTypeIndicators();
|
||||
SqmExpressible<?> nodeType = argument.getNodeType();
|
||||
FunctionParameterType type = count < types.length ? types[count++] : types[types.length - 1];
|
||||
if ( nodeType!=null ) {
|
||||
if ( nodeType != null ) {
|
||||
JavaType<?> javaType = nodeType.getExpressibleJavaType();
|
||||
if (javaType != null) {
|
||||
try {
|
||||
final JdbcType jdbcType = getJdbcType( metamodel, argument, indicators, javaType );
|
||||
checkType(
|
||||
count, functionName, type,
|
||||
jdbcType.getDefaultSqlTypeCode(),
|
||||
getJdbcType( typeConfiguration, argument, indicators, javaType ),
|
||||
javaType.getJavaTypeClass()
|
||||
);
|
||||
}
|
||||
|
@ -128,43 +141,63 @@ public class ArgumentTypesValidator implements ArgumentsValidator {
|
|||
}
|
||||
}
|
||||
|
||||
private JdbcType getJdbcType(
|
||||
MappingMetamodel metamodel,
|
||||
private int getJdbcType(
|
||||
TypeConfiguration typeConfiguration,
|
||||
SqmTypedNode<?> argument,
|
||||
JdbcTypeIndicators indicators,
|
||||
JavaType<?> javaType) {
|
||||
// For enum types, we must try to resolve the JdbcMapping of a possible path
|
||||
// to be sure we use the correct JdbcType for the validation
|
||||
final JdbcMapping mapping = javaType.getJavaTypeClass().isEnum()
|
||||
? getJdbcMapping( argument, metamodel )
|
||||
: null;
|
||||
if ( mapping == null ) {
|
||||
return javaType.getRecommendedJdbcType( indicators );
|
||||
final JdbcType jdbcType;
|
||||
if ( javaType.getJavaTypeClass().isEnum() ) {
|
||||
// we can't tell from the enum class whether it is mapped
|
||||
// as STRING or ORDINAL, we have to look at the entity
|
||||
// attribute it belongs to when it occurs as a path expression
|
||||
final JdbcMapping mapping = getJdbcMappingForEnum( argument, typeConfiguration );
|
||||
if ( mapping == null ) {
|
||||
jdbcType = javaType.getRecommendedJdbcType( indicators );
|
||||
}
|
||||
else {
|
||||
// indicates that we don't know if its STRING or ORDINAL
|
||||
return ENUM_UNKNOWN_JDBC_TYPE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return mapping.getJdbcType();
|
||||
jdbcType = javaType.getRecommendedJdbcType( indicators );
|
||||
}
|
||||
return jdbcType.getDefaultSqlTypeCode();
|
||||
}
|
||||
|
||||
private JdbcMapping getJdbcMapping(SqmTypedNode<?> argument, MappingMetamodel metamodel) {
|
||||
private JdbcMapping getJdbcMappingForEnum(SqmTypedNode<?> argument, TypeConfiguration typeConfiguration) {
|
||||
if ( argument instanceof SqmPath<?> ) {
|
||||
final SqmPath<?> path = (SqmPath<?>) argument;
|
||||
final ModelPartContainer modelPartContainer = getModelPartContainer( path.getLhs(), metamodel );
|
||||
final ModelPartContainer modelPartContainer = getModelPartContainer( path.getLhs(), typeConfiguration );
|
||||
final ModelPart part = modelPartContainer.findSubPart( path.getReferencedPathSource().getPathName(), null );
|
||||
return part.getJdbcMappings().get( 0 );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ModelPartContainer getModelPartContainer(SqmPath<?> path, MappingMetamodel metamodel) {
|
||||
/**
|
||||
* @implNote Accesses the given {@link MappingMetamodel}, which is problematic.
|
||||
*/
|
||||
private ModelPartContainer getModelPartContainer(SqmPath<?> path, TypeConfiguration typeConfiguration) {
|
||||
final SqmPath<?> lhs = path.getLhs();
|
||||
if ( lhs == null ) {
|
||||
assert path instanceof SqmFrom<?, ?>;
|
||||
final EntityDomainType<?> entityDomainType = (EntityDomainType<?>) path.getNodeType().getSqmPathType();
|
||||
return metamodel.getEntityDescriptor( entityDomainType.getHibernateEntityName() );
|
||||
final MappingMetamodelImplementor mappingMetamodel;
|
||||
try {
|
||||
mappingMetamodel = typeConfiguration.getSessionFactory().getMappingMetamodel();
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
// we don't have a SessionFactory, or a MappingMetamodel
|
||||
return null;
|
||||
}
|
||||
return mappingMetamodel.getEntityDescriptor( entityDomainType.getHibernateEntityName() );
|
||||
}
|
||||
else {
|
||||
final ModelPartContainer modelPartContainer = getModelPartContainer( lhs, metamodel );
|
||||
final ModelPartContainer modelPartContainer = getModelPartContainer( lhs, typeConfiguration );
|
||||
return (ModelPartContainer) modelPartContainer.findSubPart( path.getReferencedPathSource().getPathName(), null );
|
||||
}
|
||||
}
|
||||
|
@ -225,7 +258,7 @@ public class ArgumentTypesValidator implements ArgumentsValidator {
|
|||
}
|
||||
break;
|
||||
case STRING:
|
||||
if ( !isCharacterType(code) ) {
|
||||
if ( !isCharacterType(code) && code != ENUM_UNKNOWN_JDBC_TYPE ) {
|
||||
throwError(type, javaType, functionName, count);
|
||||
}
|
||||
break;
|
||||
|
@ -240,7 +273,7 @@ public class ArgumentTypesValidator implements ArgumentsValidator {
|
|||
}
|
||||
break;
|
||||
case INTEGER:
|
||||
if ( !isIntegral(code) ) {
|
||||
if ( !isIntegral(code) && code != ENUM_UNKNOWN_JDBC_TYPE ) {
|
||||
throwError(type, javaType, functionName, count);
|
||||
}
|
||||
break;
|
||||
|
@ -291,7 +324,7 @@ public class ArgumentTypesValidator implements ArgumentsValidator {
|
|||
|
||||
@Override
|
||||
public String getSignature() {
|
||||
String sig = this.delegate.getSignature();
|
||||
String sig = delegate.getSignature();
|
||||
for (int i=0; i<types.length; i++) {
|
||||
String argName = types.length == 1 ? "arg" : "arg" + i;
|
||||
sig = sig.replace(argName, types[i] + " " + argName);
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm.produce.function;
|
||||
|
||||
import org.hibernate.metamodel.MappingMetamodel;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -25,17 +25,17 @@ public interface ArgumentsValidator {
|
|||
/**
|
||||
* Perform validation that may be done using the {@link SqmTypedNode} tree and assigned Java types.
|
||||
*
|
||||
* @deprecated Use {@link #validate(List, String, MappingMetamodel)}
|
||||
* @deprecated Use {@link #validate(List, String, TypeConfiguration)}
|
||||
*/
|
||||
@Deprecated(since = "6.2")
|
||||
default void validate(List<? extends SqmTypedNode<?>> arguments, String functionName, QueryEngine queryEngine) {
|
||||
validate( arguments, functionName, queryEngine.getTypeConfiguration().getSessionFactory().getMappingMetamodel() );
|
||||
validate( arguments, functionName, queryEngine.getTypeConfiguration() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform validation that may be done using the {@link SqmTypedNode} tree and assigned Java types.
|
||||
*/
|
||||
default void validate(List<? extends SqmTypedNode<?>> arguments, String functionName, MappingMetamodel metamodel) {}
|
||||
default void validate(List<? extends SqmTypedNode<?>> arguments, String functionName, TypeConfiguration typeConfiguration) {}
|
||||
|
||||
/**
|
||||
* Pretty-print the signature of the argument list.
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
package org.hibernate.query.sqm.produce.function;
|
||||
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.metamodel.MappingMetamodel;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -43,7 +43,7 @@ public final class StandardArgumentsValidators {
|
|||
public void validate(
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
String functionName,
|
||||
MappingMetamodel metamodel) {
|
||||
TypeConfiguration typeConfiguration) {
|
||||
if ( !arguments.isEmpty() ) {
|
||||
throw new QueryException(
|
||||
String.format(
|
||||
|
@ -71,7 +71,7 @@ public final class StandardArgumentsValidators {
|
|||
public void validate(
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
String functionName,
|
||||
MappingMetamodel metamodel) {
|
||||
TypeConfiguration typeConfiguration) {
|
||||
if ( arguments.size() < minNumOfArgs ) {
|
||||
throw new QueryException(
|
||||
String.format(
|
||||
|
@ -108,7 +108,7 @@ public final class StandardArgumentsValidators {
|
|||
public void validate(
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
String functionName,
|
||||
MappingMetamodel metamodel) {
|
||||
TypeConfiguration typeConfiguration) {
|
||||
if ( arguments.size() != number ) {
|
||||
throw new QueryException(
|
||||
String.format(
|
||||
|
@ -147,7 +147,7 @@ public final class StandardArgumentsValidators {
|
|||
public void validate(
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
String functionName,
|
||||
MappingMetamodel metamodel) {
|
||||
TypeConfiguration typeConfiguration) {
|
||||
if ( arguments.size() > maxNumOfArgs ) {
|
||||
throw new QueryException(
|
||||
String.format(
|
||||
|
@ -182,7 +182,7 @@ public final class StandardArgumentsValidators {
|
|||
public void validate(
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
String functionName,
|
||||
MappingMetamodel metamodel) {
|
||||
TypeConfiguration typeConfiguration) {
|
||||
if (arguments.size() < minNumOfArgs || arguments.size() > maxNumOfArgs) {
|
||||
throw new QueryException(
|
||||
String.format(
|
||||
|
@ -221,7 +221,7 @@ public final class StandardArgumentsValidators {
|
|||
public void validate(
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
String functionName,
|
||||
MappingMetamodel metamodel) {
|
||||
TypeConfiguration typeConfiguration) {
|
||||
for ( SqmTypedNode<?> argument : arguments ) {
|
||||
Class<?> argType = argument.getNodeJavaType().getJavaTypeClass();
|
||||
if ( !javaType.isAssignableFrom( argType ) ) {
|
||||
|
@ -250,11 +250,11 @@ public final class StandardArgumentsValidators {
|
|||
public void validate(
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
String functionName,
|
||||
MappingMetamodel metamodel) {
|
||||
TypeConfiguration typeConfiguration) {
|
||||
validators.forEach( individualValidator -> individualValidator.validate(
|
||||
arguments,
|
||||
functionName,
|
||||
metamodel
|
||||
typeConfiguration
|
||||
) );
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue