Treat PREFERRED_BOOLEAN_JDBC_TYPE_CODE value BIT like BOOLEAN and only consider the value in CastFunction
This commit is contained in:
parent
fc3c20f669
commit
0fd5fe7d5e
|
@ -453,7 +453,13 @@ public abstract class Dialect implements ConversionContext {
|
|||
//about but in certain cases it doesn't allow some useful typecasts,
|
||||
//which must be emulated in a dialect-specific way
|
||||
|
||||
queryEngine.getSqmFunctionRegistry().register("cast", new CastFunction(this));
|
||||
queryEngine.getSqmFunctionRegistry().register(
|
||||
"cast",
|
||||
new CastFunction(
|
||||
this,
|
||||
queryEngine.getPreferredSqlTypeCodeForBoolean()
|
||||
)
|
||||
);
|
||||
|
||||
//ANSI SQL extract() function is supported on the databases we care most
|
||||
//about (though it is called datepart() in some of them) but HQL defines
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
|
@ -27,32 +28,52 @@ import org.hibernate.sql.ast.tree.expression.Expression;
|
|||
*/
|
||||
public class CastFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||
|
||||
private Dialect dialect;
|
||||
private final Dialect dialect;
|
||||
private final CastType booleanCastType;
|
||||
|
||||
public CastFunction(Dialect dialect) {
|
||||
public CastFunction(Dialect dialect, int preferredSqlTypeCodeForBoolean) {
|
||||
super(
|
||||
"cast",
|
||||
StandardArgumentsValidators.exactly( 2 ),
|
||||
StandardFunctionReturnTypeResolvers.useArgType( 2 )
|
||||
);
|
||||
this.dialect = dialect;
|
||||
this.booleanCastType = getBooleanCastType( preferredSqlTypeCodeForBoolean );
|
||||
}
|
||||
|
||||
private CastType getBooleanCastType(int preferredSqlTypeCodeForBoolean) {
|
||||
switch ( preferredSqlTypeCodeForBoolean ) {
|
||||
case Types.BIT:
|
||||
case Types.SMALLINT:
|
||||
case Types.TINYINT:
|
||||
return CastType.INTEGER_BOOLEAN;
|
||||
}
|
||||
return CastType.BOOLEAN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(SqlAppender sqlAppender, List<SqlAstNode> arguments, SqlAstWalker walker) {
|
||||
final Expression source = (Expression) arguments.get( 0 );
|
||||
final JdbcMapping sourceMapping = ( (SqlExpressable) source.getExpressionType() ).getJdbcMapping();
|
||||
final CastType sourceType = sourceMapping.getCastType();
|
||||
final CastType sourceType = getCastType( sourceMapping );
|
||||
|
||||
final CastTarget castTarget = (CastTarget) arguments.get( 1 );
|
||||
final JdbcMapping targetJdbcMapping = castTarget.getExpressionType().getJdbcMapping();
|
||||
final CastType targetType = targetJdbcMapping.getCastType();
|
||||
final CastType targetType = getCastType( targetJdbcMapping );
|
||||
|
||||
String cast = dialect.castPattern( sourceType, targetType );
|
||||
|
||||
new PatternRenderer( cast ).render( sqlAppender, arguments, walker );
|
||||
}
|
||||
|
||||
private CastType getCastType(JdbcMapping sourceMapping) {
|
||||
final CastType castType = sourceMapping.getCastType();
|
||||
if ( castType == CastType.BOOLEAN ) {
|
||||
return booleanCastType;
|
||||
}
|
||||
return castType;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
|
||||
// List<SqmTypedNode<?>> arguments,
|
||||
|
|
|
@ -70,6 +70,7 @@ public class QueryEngine {
|
|||
return new QueryEngine(
|
||||
() -> sessionFactory.getRuntimeMetamodels().getJpaMetamodel(),
|
||||
sessionFactory.getSessionFactoryOptions().getCriteriaValueHandlingMode(),
|
||||
sessionFactory.getSessionFactoryOptions().getPreferredSqlTypeCodeForBoolean(),
|
||||
metadata.buildNamedQueryRepository( sessionFactory ),
|
||||
hqlTranslator,
|
||||
sqmTranslatorFactory,
|
||||
|
@ -88,10 +89,12 @@ public class QueryEngine {
|
|||
private final NativeQueryInterpreter nativeQueryInterpreter;
|
||||
private final QueryInterpretationCache interpretationCache;
|
||||
private final SqmFunctionRegistry sqmFunctionRegistry;
|
||||
private final int preferredSqlTypeCodeForBoolean;
|
||||
|
||||
public QueryEngine(
|
||||
Supplier<JpaMetamodel> jpaMetamodelAccess,
|
||||
ValueHandlingMode criteriaValueHandlingMode,
|
||||
int preferredSqlTypeCodeForBoolean,
|
||||
NamedObjectRepository namedObjectRepository,
|
||||
HqlTranslator hqlTranslator,
|
||||
SqmTranslatorFactory sqmTranslatorFactory,
|
||||
|
@ -114,6 +117,7 @@ public class QueryEngine {
|
|||
);
|
||||
|
||||
this.sqmFunctionRegistry = new SqmFunctionRegistry();
|
||||
this.preferredSqlTypeCodeForBoolean = preferredSqlTypeCodeForBoolean;
|
||||
dialect.initializeFunctionRegistry( this );
|
||||
if ( userDefinedRegistry != null ) {
|
||||
userDefinedRegistry.overlay( sqmFunctionRegistry );
|
||||
|
@ -137,6 +141,7 @@ public class QueryEngine {
|
|||
public QueryEngine(
|
||||
JpaMetamodel jpaMetamodel,
|
||||
ValueHandlingMode criteriaValueHandlingMode,
|
||||
int preferredSqlTypeCodeForBoolean,
|
||||
boolean useStrictJpaCompliance,
|
||||
NamedObjectRepository namedObjectRepository,
|
||||
NativeQueryInterpreter nativeQueryInterpreter,
|
||||
|
@ -147,6 +152,7 @@ public class QueryEngine {
|
|||
this.nativeQueryInterpreter = nativeQueryInterpreter;
|
||||
|
||||
this.sqmFunctionRegistry = new SqmFunctionRegistry();
|
||||
this.preferredSqlTypeCodeForBoolean = preferredSqlTypeCodeForBoolean;
|
||||
dialect.initializeFunctionRegistry( this );
|
||||
|
||||
this.criteriaBuilder = new SqmCriteriaNodeBuilder(
|
||||
|
@ -367,4 +373,8 @@ public class QueryEngine {
|
|||
sqmFunctionRegistry.close();
|
||||
}
|
||||
}
|
||||
|
||||
public int getPreferredSqlTypeCodeForBoolean() {
|
||||
return preferredSqlTypeCodeForBoolean;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.type;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.type.descriptor.java.BooleanTypeDescriptor;
|
||||
|
@ -60,10 +61,12 @@ public class BooleanType
|
|||
|
||||
@Override
|
||||
public <X> BasicType<X> resolveIndicatedType(SqlTypeDescriptorIndicators indicators) {
|
||||
if ( indicators.getPreferredSqlTypeCodeForBoolean() != getSqlTypeDescriptor().getJdbcTypeCode() ) {
|
||||
final int preferredSqlTypeCodeForBoolean = indicators.getPreferredSqlTypeCodeForBoolean();
|
||||
// We treat BIT like BOOLEAN because it uses the same JDBC access methods
|
||||
if ( preferredSqlTypeCodeForBoolean != Types.BIT && preferredSqlTypeCodeForBoolean != getSqlTypeDescriptor().getJdbcTypeCode() ) {
|
||||
final SqlTypeDescriptor sqlTypeDescriptor = indicators.getTypeConfiguration()
|
||||
.getSqlTypeDescriptorRegistry()
|
||||
.getDescriptor( indicators.getPreferredSqlTypeCodeForBoolean() );
|
||||
.getDescriptor( preferredSqlTypeCodeForBoolean );
|
||||
//noinspection unchecked
|
||||
return (BasicType<X>) indicators.getTypeConfiguration()
|
||||
.getBasicTypeRegistry()
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.hibernate.boot.spi.BootstrapContext;
|
|||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.jpa.JpaComplianceStub;
|
||||
import org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting;
|
||||
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
||||
|
@ -118,6 +119,7 @@ public class HqlTranslationNoFactoryTests {
|
|||
final QueryEngine queryEngine = new QueryEngine(
|
||||
jpaMetamodel,
|
||||
ValueHandlingMode.BIND,
|
||||
ConfigurationHelper.getPreferredSqlTypeCodeForBoolean( registryScope.getRegistry() ),
|
||||
// we don't want strict JPA query compliance
|
||||
false,
|
||||
new NamedObjectRepositoryImpl( Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap() ),
|
||||
|
|
Loading…
Reference in New Issue