Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various changes around dialects #9638

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,27 @@
public interface DialectSpecificSettings {
/**
* Specifies whether this database is running on an Autonomous Database Cloud Service.
* <p>
* Ignored if Hibernate is able to determine this by querying the Oracle server at startup.
*
* @settingDefault {@code false}
*/
String ORACLE_AUTONOMOUS_DATABASE = "hibernate.dialect.oracle.is_autonomous";

/**
* Specifies whether this database's {@code MAX_STRING_SIZE} is set to {@code EXTENDED}.
* Specifies whether {@code MAX_STRING_SIZE} is set to {@code EXTENDED} on Oracle.
* <p>
* Ignored if Hibernate is able to determine the value of {@code MAX_STRING_SIZE} by
* querying the Oracle server at startup.
*
* @settingDefault {@code false}
*/
String ORACLE_EXTENDED_STRING_SIZE = "hibernate.dialect.oracle.extended_string_size";

/**
* Specifies whether this database is accessed using a database service protected by Application Continuity.
* <p>
* Ignored if Hibernate is able to determine this by querying the Oracle server at startup.
*
* @settingDefault {@code false}
*
Expand All @@ -37,14 +44,20 @@ public interface DialectSpecificSettings {
String ORACLE_APPLICATION_CONTINUITY = "hibernate.dialect.oracle.application_continuity";

/**
* Specifies whether this database's {@code ansinull} setting is enabled.
* Specifies whether the {@code ansinull} setting is enabled on Sybase.
* <p>
* Ignored if Hibernate is able to determine the value of {@code ansinull}
* by querying the server {@code @@options} at startup.
*
* @settingDefault {@code false}
*/
String SYBASE_ANSI_NULL = "hibernate.dialect.sybase.extended_string_size";

/**
* Specifies the maximum page size on Sybase.
* <p>
* Ignored if Hibernate is able to determine the page size by querying the
* server {@code @@maxpagesize} at startup.
*
* @settingDefault {@value org.hibernate.dialect.SybaseASEDialect#MAX_PAGE_SIZE}
*/
Expand All @@ -53,13 +66,19 @@ public interface DialectSpecificSettings {
/**
* Specifies the bytes per character to use based on the database's configured
* <a href="https://dev.mysql.com/doc/refman/8.0/en/charset-charsets.html">charset</a>.
* <p>
* Ignored if Hibernate is able to determine the character set by querying the
* server {@code @@character_set_database} at startup.
*
* @settingDefault {@code 4}
*/
String MYSQL_BYTES_PER_CHARACTER = "hibernate.dialect.mysql.bytes_per_character";

/**
* Specifies whether the {@code NO_BACKSLASH_ESCAPES} sql mode is enabled.
* <p>
* Ignored if Hibernate is able to determine this by querying the server
* {@code @@sql_mode} at startup.
*
* @settingDefault {@code false}
*/
Expand All @@ -69,18 +88,28 @@ public interface DialectSpecificSettings {
* Specifies a custom CockroachDB version string. The expected format of the string is
* the one returned from the {@code version()} function, e.g.:
* {@code "CockroachDB CCL v23.1.8 (x86_64-pc-linux-gnu, built 2023/08/04 18:11:44, go1.19.10)"}
* <p>
* Ignored if Hibernate is able to obtain the version string by querying the server at startup.
*/
String COCKROACH_VERSION_STRING = "hibernate.dialect.cockroach.version_string";

/**
* Specifies the compatibility level of the SQL Server database as returned by {@code select compatibility_level from sys.databases}.
* The number has three digits, the first two digits are the major version, the last digit is the minor version.
* Specifies the compatibility level of the SQL Server database as returned by
* {@code select compatibility_level from sys.databases}.
* <p>
* The number has three digits: the first two digits are the major version,
* the last digit is the minor version.
* <p>
* Ignored if Hibernate is able to determine this by querying the {@code sys.databases}
* table at startup.
*/
String SQL_SERVER_COMPATIBILITY_LEVEL = "hibernate.dialect.sqlserver.compatibility_level";

/**
* Specifies the LOB prefetch size. LOBs larger than this value will be read into memory as the HANA JDBC driver closes
* the LOB when the result set is closed.
* Specifies the LOB prefetch size. LOBs larger than this value will be read into
* memory as the HANA JDBC driver closes the LOB when the result set is closed.
* <p>
* Ignored if Hibernate is able to determine this by querying the server at startup.
*
* @settingDefault {@code 1024}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
import org.hibernate.PessimisticLockException;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.FetchSettings;
import org.hibernate.dialect.aggregate.AggregateSupport;
import org.hibernate.dialect.aggregate.MySQLAggregateSupport;
import org.hibernate.dialect.function.CommonFunctionFactory;
Expand All @@ -45,7 +47,6 @@
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.CheckConstraint;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
Expand Down Expand Up @@ -89,6 +90,7 @@
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
import static org.hibernate.internal.util.JdbcExceptionHelper.extractSqlState;
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
import static org.hibernate.internal.util.StringHelper.split;
import static org.hibernate.type.SqlTypes.BIGINT;
import static org.hibernate.type.SqlTypes.BINARY;
import static org.hibernate.type.SqlTypes.BIT;
Expand Down Expand Up @@ -217,7 +219,7 @@ protected static DatabaseVersion createVersion(DialectResolutionInfo info) {
protected static DatabaseVersion createVersion(DialectResolutionInfo info, DatabaseVersion defaultVersion) {
final String versionString = info.getDatabaseVersion();
if ( versionString != null ) {
final String[] components = StringHelper.split( ".-", versionString );
final String[] components = split( ".-", versionString );
if ( components.length >= 3 ) {
try {
final int majorVersion = parseInt( components[0] );
Expand All @@ -241,26 +243,19 @@ protected DatabaseVersion getMinimumSupportedVersion() {
@Override
protected void initDefaultProperties() {
super.initDefaultProperties();
getDefaultProperties().setProperty( Environment.MAX_FETCH_DEPTH, "2" );
getDefaultProperties().setProperty( FetchSettings.MAX_FETCH_DEPTH, "2" );
}

private MySQLStorageEngine createStorageEngine() {
String storageEngine = Environment.getProperties().getProperty( Environment.STORAGE_ENGINE );
if (storageEngine == null) {
storageEngine = System.getProperty( Environment.STORAGE_ENGINE );
}
if (storageEngine == null) {
return getDefaultMySQLStorageEngine();
}
else if( "innodb".equalsIgnoreCase( storageEngine ) ) {
return InnoDBStorageEngine.INSTANCE;
}
else if( "myisam".equalsIgnoreCase( storageEngine ) ) {
return MyISAMStorageEngine.INSTANCE;
}
else {
throw new UnsupportedOperationException( "The " + storageEngine + " storage engine is not supported" );
}
final String storageEngine = Environment.getProperties().getProperty( AvailableSettings.STORAGE_ENGINE );
return storageEngine == null
? getDefaultMySQLStorageEngine()
: switch ( storageEngine ) {
case "innodb" -> InnoDBStorageEngine.INSTANCE;
case "myisam" -> MyISAMStorageEngine.INSTANCE;
default -> throw new UnsupportedOperationException(
"The '" + storageEngine + "' storage engine is not supported" );
};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@
import org.hibernate.dialect.temptable.TemporaryTableKind;
import org.hibernate.dialect.unique.CreateTableUniqueDelegate;
import org.hibernate.dialect.unique.UniqueDelegate;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.config.spi.StandardConverters;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
Expand Down Expand Up @@ -86,7 +84,6 @@
import org.hibernate.type.NullType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.NullJdbcType;
import org.hibernate.type.descriptor.jdbc.ObjectNullAsNullTypeJdbcType;
Expand All @@ -108,8 +105,6 @@
import static org.hibernate.LockOptions.SKIP_LOCKED;
import static org.hibernate.LockOptions.WAIT_FOREVER;
import static org.hibernate.cfg.AvailableSettings.BATCH_VERSIONED_DATA;
import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_EXTENDED_STRING_SIZE;
import static org.hibernate.cfg.DialectSpecificSettings.ORACLE_AUTONOMOUS_DATABASE;
import static org.hibernate.dialect.OracleJdbcHelper.getArrayJdbcTypeConstructor;
import static org.hibernate.dialect.OracleJdbcHelper.getNestedTableJdbcTypeConstructor;
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
Expand Down Expand Up @@ -168,12 +163,11 @@ public class OracleDialect extends Dialect {
private static final Pattern SQL_STATEMENT_TYPE_PATTERN =
Pattern.compile( "^(?:/\\*.*?\\*/)?\\s*(select|insert|update|delete)\\s+.*?", CASE_INSENSITIVE );

private static final int PARAM_LIST_SIZE_LIMIT_1000 = 1000;

/** Starting from 23c, 65535 parameters are supported for the IN condition. */
/**
* Starting from 23c, 65535 parameters are supported for the {@code IN} condition.
*/
private static final int PARAM_LIST_SIZE_LIMIT_65535 = 65535;

public static final String PREFER_LONG_RAW = "hibernate.dialect.oracle.prefer_long_raw";
private static final int PARAM_LIST_SIZE_LIMIT_1000 = 1000;

private static final String yqmSelect =
"(trunc(%2$s, 'MONTH') + numtoyminterval(%1$s, 'MONTH') + (least(extract(day from %2$s), extract(day from last_day(trunc(%2$s, 'MONTH') + numtoyminterval(%1$s, 'MONTH')))) - 1))";
Expand All @@ -191,11 +185,10 @@ public class OracleDialect extends Dialect {
@Override
protected void applyAggregateColumnCheck(StringBuilder buf, AggregateColumn aggregateColumn) {
final JdbcType jdbcType = aggregateColumn.getType().getJdbcType();
if ( dialect.getVersion().isBefore( 23, 6 ) && jdbcType.isXml() ) {
// ORA-00600 when selecting XML columns that have a check constraint was fixed in 23.6
return;
// ORA-00600 when selecting XML columns that have a check constraint was fixed in 23.6
if ( !dialect.getVersion().isBefore( 23, 6 ) || !jdbcType.isXml() ) {
super.applyAggregateColumnCheck( buf, aggregateColumn );
}
super.applyAggregateColumnCheck( buf, aggregateColumn );
}
};

Expand Down Expand Up @@ -239,40 +232,6 @@ public OracleDialect(DialectResolutionInfo info, OracleServerConfiguration serve
this.driverMajorVersion = serverConfiguration.getDriverMajorVersion();
}

@Deprecated( since = "6.4" )
protected static boolean isExtended(DialectResolutionInfo info) {
final DatabaseMetaData databaseMetaData = info.getDatabaseMetadata();
if ( databaseMetaData != null ) {
try ( java.sql.Statement statement = databaseMetaData.getConnection().createStatement() ) {
statement.execute( "select cast('string' as varchar2(32000)) from dual" );
// succeeded, so MAX_STRING_SIZE == EXTENDED
return true;
}
catch ( SQLException ex ) {
// failed, so MAX_STRING_SIZE == STANDARD
// Ignore
}
}
// default to the dialect-specific configuration setting
return ConfigurationHelper.getBoolean( ORACLE_EXTENDED_STRING_SIZE, info.getConfigurationValues(), false );
}

@Deprecated( since = "6.4" )
protected static boolean isAutonomous(DialectResolutionInfo info) {
final DatabaseMetaData databaseMetaData = info.getDatabaseMetadata();
if ( databaseMetaData != null ) {
try ( java.sql.Statement statement = databaseMetaData.getConnection().createStatement() ) {
return statement.executeQuery( "select 1 from dual where sys_context('USERENV','CLOUD_SERVICE') in ('OLTP','DWCS','JSON')" )
.next();
}
catch ( SQLException ex ) {
// Ignore
}
}
// default to the dialect-specific configuration setting
return ConfigurationHelper.getBoolean( ORACLE_AUTONOMOUS_DATABASE, info.getConfigurationValues(), false );
}

public boolean isAutonomous() {
return autonomous;
}
Expand Down Expand Up @@ -360,12 +319,12 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
functionFactory.coalesce();

functionContributions.getFunctionRegistry()
.patternDescriptorBuilder( "bitor", "(?1+?2-bitand(?1,?2))")
.patternDescriptorBuilder( "bitor", "(?1+?2-bitand(?1,?2))" )
.setExactArgumentCount( 2 )
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
.register();
functionContributions.getFunctionRegistry()
.patternDescriptorBuilder( "bitxor", "(?1+?2-2*bitand(?1,?2))")
.patternDescriptorBuilder( "bitxor", "(?1+?2-2*bitand(?1,?2))" )
.setExactArgumentCount( 2 )
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
.register();
Expand Down Expand Up @@ -1019,12 +978,6 @@ public void contributeTypes(TypeContributions typeContributions, ServiceRegistry
typeContributions.contributeJdbcType( OracleReflectionStructJdbcType.INSTANCE );
}

// account for Oracle's deprecated support for LONGVARBINARY
// prefer BLOB, unless the user explicitly opts out
final boolean preferLong = serviceRegistry.requireService( ConfigurationService.class )
.getSetting( PREFER_LONG_RAW, StandardConverters.BOOLEAN, false );
typeContributions.contributeJdbcType( preferLong ? BlobJdbcType.PRIMITIVE_ARRAY_BINDING : BlobJdbcType.DEFAULT );

if ( getVersion().isSameOrAfter( 21 ) ) {
typeContributions.contributeJdbcType( OracleJsonJdbcType.INSTANCE );
typeContributions.contributeJdbcTypeConstructor( OracleJsonArrayJdbcTypeConstructor.NATIVE_INSTANCE );
Expand Down Expand Up @@ -1065,10 +1018,10 @@ public void contributeTypes(TypeContributions typeContributions, ServiceRegistry
)
);

if(getVersion().isSameOrAfter(23)) {
if ( getVersion().isSameOrAfter(23) ) {
final JdbcTypeRegistry jdbcTypeRegistry = typeContributions.getTypeConfiguration().getJdbcTypeRegistry();
jdbcTypeRegistry.addDescriptor(OracleEnumJdbcType.INSTANCE);
jdbcTypeRegistry.addDescriptor(OracleOrdinalEnumJdbcType.INSTANCE);
jdbcTypeRegistry.addDescriptor( OracleEnumJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptor( OracleOrdinalEnumJdbcType.INSTANCE );
}
}

Expand Down
Loading
Loading