HHH-15752 Add Boolean support to oracle dialect

This commit is contained in:
Emmanuel Jannetti 2024-03-28 10:50:58 +01:00 committed by Christian Beikov
parent fcab4df57d
commit 320e282ccc
5 changed files with 34 additions and 10 deletions

View File

@ -66,6 +66,8 @@ public final class BooleanDecoder {
return "decode(?1,1,'Y',0,'N',null)";
case TF_BOOLEAN:
return "decode(?1,'T','Y','F','N',null)";
case BOOLEAN:
return "decode(?1,true,'Y',false,'N',null)";
case INTEGER:
case LONG:
return "decode(abs(sign(?1)),1,'Y',0,'N',null)";
@ -81,6 +83,8 @@ public final class BooleanDecoder {
return "decode(?1,1,'T',0,'F',null)";
case YN_BOOLEAN:
return "decode(?1,'Y','T','N','F',null)";
case BOOLEAN:
return "decode(?1,true,'T',false,'F',null)";
case INTEGER:
case LONG:
return "decode(abs(sign(?1)),1,'T',0,'F',null)";

View File

@ -253,7 +253,7 @@ public class OracleDialect extends Dialect {
@Override
public int getPreferredSqlTypeCodeForBoolean() {
return Types.BIT;
return getVersion().isSameOrAfter( 23 ) ? super.getPreferredSqlTypeCodeForBoolean() : Types.BIT;
}
@Override
@ -425,7 +425,6 @@ public class OracleDialect extends Dialect {
}
/**
* Oracle doesn't have any sort of {@link Types#BOOLEAN}
* type or {@link Types#TIME} type, and its default behavior
* for casting dates and timestamps to and from strings is just awful.
*/
@ -453,6 +452,11 @@ public class OracleDialect extends Dialect {
}
break;
case BOOLEAN:
result = BooleanDecoder.toBoolean( from );
if ( result != null ) {
return result;
}
break;
case TF_BOOLEAN:
result = BooleanDecoder.toTrueFalseBoolean( from );
if ( result != null ) {
@ -461,6 +465,7 @@ public class OracleDialect extends Dialect {
break;
case STRING:
switch ( from ) {
case BOOLEAN:
case INTEGER_BOOLEAN:
case TF_BOOLEAN:
case YN_BOOLEAN:
@ -700,9 +705,12 @@ public class OracleDialect extends Dialect {
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
case BOOLEAN:
// still, after all these years...
return "number(1,0)";
if ( getVersion().isSameOrAfter( 23 ) ) {
return super.columnType( sqlTypeCode );
}
else {
return "number(1,0)";
}
case TINYINT:
return "number(3,0)";
case SMALLINT:
@ -902,8 +910,10 @@ public class OracleDialect extends Dialect {
@Override
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.contributeTypes( typeContributions, serviceRegistry );
typeContributions.contributeJdbcType( OracleBooleanJdbcType.INSTANCE );
if ( getVersion().isBefore( 23 ) ) {
// starting 23c we support Boolean type natively
typeContributions.contributeJdbcType( OracleBooleanJdbcType.INSTANCE );
}
typeContributions.contributeJdbcType( OracleXmlJdbcType.INSTANCE );
if ( OracleJdbcHelper.isUsable( serviceRegistry ) ) {
typeContributions.contributeJdbcType( OracleJdbcHelper.getStructJdbcType( serviceRegistry ) );

View File

@ -25,9 +25,11 @@ import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.annotations.Struct;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.procedure.ProcedureCall;
import org.hibernate.query.procedure.ProcedureParameter;
import org.hibernate.testing.orm.junit.SkipForDialect;
import org.hibernate.type.SqlTypes;
import org.hibernate.testing.jdbc.SharedDriverManagerTypeCacheClearingIntegrator;
@ -252,6 +254,7 @@ public class JsonWithArrayEmbeddableTest {
@Test
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsJsonComponentUpdate.class)
@SkipForDialect( dialectClass = OracleDialect.class, reason = "External driver fix required")
public void testUpdateAllAggregateMembers(SessionFactoryScope scope) {
scope.inTransaction(
entityManager -> {

View File

@ -49,6 +49,7 @@ import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.Setting;
import org.hibernate.testing.orm.junit.SkipForDialect;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -283,6 +284,7 @@ public class StructWithArrayEmbeddableTest implements AdditionalMappingContribut
}
@Test
@SkipForDialect( dialectClass = OracleDialect.class, reason = "External driver fix required")
public void testSelectionItems(SessionFactoryScope scope) {
scope.inSession(
entityManager -> {

View File

@ -73,6 +73,7 @@ public class BooleanArrayTest {
}
@Test
@SkipForDialect( dialectClass = OracleDialect.class, reason = "External driver fix required")
public void testById(SessionFactoryScope scope) {
scope.inSession( em -> {
TableWithBooleanArrays tableRecord;
@ -88,8 +89,9 @@ public class BooleanArrayTest {
}
@Test
@SkipForDialect( dialectClass = OracleDialect.class, reason = "External driver fix required")
public void testQueryById(SessionFactoryScope scope) {
scope.inSession( em -> {
scope.inSession( em -> {
TypedQuery<TableWithBooleanArrays> tq = em.createNamedQuery( "TableWithBooleanArrays.JPQL.getById", TableWithBooleanArrays.class );
tq.setParameter( "id", 2L );
TableWithBooleanArrays tableRecord = tq.getSingleResult();
@ -99,8 +101,9 @@ public class BooleanArrayTest {
@Test
@SkipForDialect(dialectClass = AbstractHANADialect.class, reason = "For some reason, HANA can't intersect VARBINARY values, but funnily can do a union...")
public void testQuery(SessionFactoryScope scope) {
scope.inSession( em -> {
@SkipForDialect( dialectClass = OracleDialect.class, reason = "External driver fix required")
public void testQuery(SessionFactoryScope scope) {
scope.inSession( em -> {
TypedQuery<TableWithBooleanArrays> tq = em.createNamedQuery( "TableWithBooleanArrays.JPQL.getByData", TableWithBooleanArrays.class );
tq.setParameter( "data", new Boolean[]{} );
TableWithBooleanArrays tableRecord = tq.getSingleResult();
@ -109,6 +112,7 @@ public class BooleanArrayTest {
}
@Test
@SkipForDialect( dialectClass = OracleDialect.class, reason = "External driver fix required")
public void testNativeQueryById(SessionFactoryScope scope) {
scope.inSession( em -> {
TypedQuery<TableWithBooleanArrays> tq = em.createNamedQuery( "TableWithBooleanArrays.Native.getById", TableWithBooleanArrays.class );
@ -136,6 +140,7 @@ public class BooleanArrayTest {
@Test
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsStructuralArrays.class)
@SkipForDialect( dialectClass = OracleDialect.class, reason = "External driver fix required")
public void testNativeQueryUntyped(SessionFactoryScope scope) {
scope.inSession( em -> {
Query q = em.createNamedQuery( "TableWithBooleanArrays.Native.getByIdUntyped" );