HHH-15535 - Remove support for H2 versions older than 2.1

Signed-off-by: Jan Schatteman <jschatte@redhat.com>
This commit is contained in:
Jan Schatteman 2023-08-17 16:44:35 +02:00 committed by Christian Beikov
parent b241502b59
commit 2220cf7fe5
14 changed files with 149248 additions and 152 deletions

4
Jenkinsfile vendored
View File

@ -126,10 +126,6 @@ stage('Build') {
try {
stage('Start database') {
switch (buildEnv.dbName) {
case "h2_1_4":
state[buildEnv.tag]['additionalOptions'] = state[buildEnv.tag]['additionalOptions'] +
" -Pgradle.libs.versions.h2=1.4.197 -Pgradle.libs.versions.h2gis=1.5.0"
break;
case "hsqldb_2_6":
state[buildEnv.tag]['additionalOptions'] = state[buildEnv.tag]['additionalOptions'] +
" -Pgradle.libs.versions.hsqldb=2.6.1"

View File

@ -1,7 +1,7 @@
#! /bin/bash
goal=
if [ "$RDBMS" == "h2" ] || [ "$RDBMS" == "h2_1_4" ]; then
if [ "$RDBMS" == "h2" ]; then
# This is the default.
goal=""
elif [ "$RDBMS" == "hsqldb" ] || [ "$RDBMS" == "hsqldb_2_6" ]; then

View File

@ -23,7 +23,6 @@ import org.hibernate.boot.model.TypeContributions;
import org.hibernate.dialect.function.CommonFunctionFactory;
import org.hibernate.dialect.hint.IndexQueryHintHandler;
import org.hibernate.dialect.identity.H2FinalTableIdentityColumnSupport;
import org.hibernate.dialect.identity.H2IdentityColumnSupport;
import org.hibernate.dialect.identity.IdentityColumnSupport;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.OffsetFetchLimitHandler;
@ -65,13 +64,10 @@ import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.sql.model.MutationOperation;
import org.hibernate.sql.model.internal.OptionalTableUpdate;
import org.hibernate.sql.model.jdbc.OptionalTableUpdateOperation;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorH2DatabaseImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.descriptor.jdbc.H2FormatJsonJdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.TimeAsTimestampWithTimeZoneJdbcType;
import org.hibernate.type.descriptor.jdbc.TimeUtcAsJdbcTimeJdbcType;
import org.hibernate.type.descriptor.jdbc.TimeUtcAsOffsetTimeJdbcType;
import org.hibernate.type.descriptor.jdbc.TimestampUtcAsInstantJdbcType;
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
@ -83,11 +79,9 @@ import org.hibernate.type.spi.TypeConfiguration;
import jakarta.persistence.TemporalType;
import static org.hibernate.query.sqm.TemporalUnit.SECOND;
import static org.hibernate.type.SqlTypes.ARRAY;
import static org.hibernate.type.SqlTypes.BIGINT;
import static org.hibernate.type.SqlTypes.BINARY;
import static org.hibernate.type.SqlTypes.CHAR;
import static org.hibernate.type.SqlTypes.DECIMAL;
import static org.hibernate.type.SqlTypes.DOUBLE;
import static org.hibernate.type.SqlTypes.FLOAT;
import static org.hibernate.type.SqlTypes.GEOMETRY;
@ -97,11 +91,9 @@ import static org.hibernate.type.SqlTypes.LONG32NVARCHAR;
import static org.hibernate.type.SqlTypes.LONG32VARBINARY;
import static org.hibernate.type.SqlTypes.LONG32VARCHAR;
import static org.hibernate.type.SqlTypes.NCHAR;
import static org.hibernate.type.SqlTypes.NUMERIC;
import static org.hibernate.type.SqlTypes.NVARCHAR;
import static org.hibernate.type.SqlTypes.OTHER;
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
import static org.hibernate.type.SqlTypes.TIME_WITH_TIMEZONE;
import static org.hibernate.type.SqlTypes.TIMESTAMP_UTC;
import static org.hibernate.type.SqlTypes.UUID;
import static org.hibernate.type.SqlTypes.VARBINARY;
import static org.hibernate.type.SqlTypes.VARCHAR;
@ -117,7 +109,7 @@ import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithN
* @author Thomas Mueller
*/
public class H2Dialect extends Dialect {
private static final DatabaseVersion MINIMUM_VERSION = DatabaseVersion.make( 1, 4, 197 );
private static final DatabaseVersion MINIMUM_VERSION = DatabaseVersion.make( 2, 1, 214 );
private final boolean ansiSequence;
private final boolean cascadeConstraints;
@ -141,25 +133,18 @@ public class H2Dialect extends Dialect {
public H2Dialect(DatabaseVersion version) {
super(version);
// supportsTuplesInSubqueries = version.isSameOrAfter( 1, 4, 198 );
// Prior to 1.4.200 there was no support for 'current value for sequence_name'
// After 2.0.202 there is no support for 'sequence_name.nextval' and 'sequence_name.currval'
ansiSequence = version.isSameOrAfter( 1, 4, 200 );
ansiSequence = true;
// Prior to 1.4.200 the 'cascade' in 'drop table' was implicit
cascadeConstraints = version.isSameOrAfter( 1, 4, 200 );
cascadeConstraints = true;
// 1.4.200 introduced changes in current_time and current_timestamp
useLocalTime = version.isSameOrAfter( 1, 4, 200 );
useLocalTime = true;
this.sequenceInformationExtractor = version.isSameOrAfter( 1, 4, 201 )
? SequenceInformationExtractorLegacyImpl.INSTANCE
: SequenceInformationExtractorH2DatabaseImpl.INSTANCE;
this.sequenceInformationExtractor = SequenceInformationExtractorLegacyImpl.INSTANCE;
this.querySequenceString = "select * from INFORMATION_SCHEMA.SEQUENCES";
this.optionalTableUpdateStrategy = version.isSameOrAfter( 1, 4, 200 )
? H2Dialect::usingMerge
: H2Dialect::withoutMerge;
this.optionalTableUpdateStrategy = H2Dialect::usingMerge;
}
private static DatabaseVersion parseVersion(DialectResolutionInfo info) {
@ -189,7 +174,7 @@ public class H2Dialect extends Dialect {
@Override
public boolean supportsStandardArrays() {
return getVersion().isSameOrAfter( 2 );
return true;
}
@Override
@ -201,13 +186,6 @@ public class H2Dialect extends Dialect {
@Override
protected String columnType(int sqlTypeCode) {
switch ( sqlTypeCode ) {
// prior to version 2.0, H2 reported NUMERIC columns as DECIMAL,
// which caused problems for schema update tool
case NUMERIC:
return getVersion().isBefore( 2 ) ? columnType( DECIMAL ) : super.columnType( sqlTypeCode );
// Support was only added in 2.0
case TIME_WITH_TIMEZONE:
return getVersion().isBefore( 2 ) ? columnType( TIMESTAMP_WITH_TIMEZONE ) : super.columnType( sqlTypeCode );
case NCHAR:
return columnType( CHAR );
case NVARCHAR:
@ -241,17 +219,10 @@ public class H2Dialect extends Dialect {
super.registerColumnTypes( typeContributions, serviceRegistry );
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
if ( getVersion().isBefore( 2 ) ) {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( ARRAY, "array", this ) );
}
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( UUID, "uuid", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOMETRY, "geometry", this ) );
if ( getVersion().isSameOrAfter( 1, 4, 198 ) ) {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( INTERVAL_SECOND, "interval second($p,$s)", this ) );
}
if ( getVersion().isSameOrAfter( 1, 4, 200 ) ) {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( JSON, "json", this ) );
}
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( INTERVAL_SECOND, "interval second($p,$s)", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( JSON, "json", this ) );
}
@Override
@ -261,22 +232,11 @@ public class H2Dialect extends Dialect {
final JdbcTypeRegistry jdbcTypeRegistry = typeContributions.getTypeConfiguration()
.getJdbcTypeRegistry();
if ( getVersion().isBefore( 2 ) ) {
// Support for TIME_WITH_TIMEZONE was only added in 2.0
jdbcTypeRegistry.addDescriptor( TimeAsTimestampWithTimeZoneJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptor( TimeUtcAsJdbcTimeJdbcType.INSTANCE );
}
else {
jdbcTypeRegistry.addDescriptor( TimeUtcAsOffsetTimeJdbcType.INSTANCE );
}
jdbcTypeRegistry.addDescriptor( TimeUtcAsOffsetTimeJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptor( TimestampUtcAsInstantJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptorIfAbsent( UUIDJdbcType.INSTANCE );
if ( getVersion().isSameOrAfter( 1, 4, 198 ) ) {
jdbcTypeRegistry.addDescriptorIfAbsent( H2DurationIntervalSecondJdbcType.INSTANCE );
}
if ( getVersion().isSameOrAfter( 1, 4, 200 ) ) {
jdbcTypeRegistry.addDescriptorIfAbsent( H2FormatJsonJdbcType.INSTANCE );
}
jdbcTypeRegistry.addDescriptorIfAbsent( H2DurationIntervalSecondJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptorIfAbsent( H2FormatJsonJdbcType.INSTANCE );
}
@Override
@ -286,7 +246,7 @@ public class H2Dialect extends Dialect {
public boolean hasOddDstBehavior() {
// H2 1.4.200 has a bug: https://github.com/h2database/h2database/issues/3184
return getVersion().isSameOrAfter( 1, 4, 200 );
return true;
}
@Override
@ -344,36 +304,17 @@ public class H2Dialect extends Dialect {
functionFactory.median();
functionFactory.stddevPopSamp();
functionFactory.varPopSamp();
if ( getVersion().isSame( 1, 4, 200 ) ) {
// See https://github.com/h2database/h2database/issues/2518
functionFactory.format_toChar();
}
else {
functionFactory.format_formatdatetime();
}
functionFactory.format_formatdatetime();
functionFactory.rownum();
if ( getVersion().isSameOrAfter( 1, 4, 200 ) ) {
functionFactory.windowFunctions();
functionFactory.inverseDistributionOrderedSetAggregates();
functionFactory.hypotheticalOrderedSetAggregates();
if ( getVersion().isSameOrAfter( 2 ) ) {
functionFactory.listagg( null );
}
else {
// Use group_concat until 2.x as listagg was buggy
functionFactory.listagg_groupConcat();
}
}
else {
functionFactory.listagg_groupConcat();
}
functionFactory.windowFunctions();
functionFactory.listagg( null );
functionFactory.inverseDistributionOrderedSetAggregates();
functionFactory.hypotheticalOrderedSetAggregates();
}
@Override
public void augmentPhysicalTableTypes(List<String> tableTypesList) {
if ( getVersion().isSameOrAfter( 2 ) ) {
tableTypesList.add( "BASE TABLE" );
}
tableTypesList.add( "BASE TABLE" );
}
@Override
@ -584,7 +525,7 @@ public class H2Dialect extends Dialect {
}
public boolean supportsTimeLiteralOffset() {
return getVersion().isSameOrAfter( 1, 4, 200 );
return true;
}
@Override
@ -823,17 +764,17 @@ public class H2Dialect extends Dialect {
@Override
public boolean supportsWindowFunctions() {
return getVersion().isSameOrAfter( 1, 4, 200 );
return true;
}
@Override
public boolean supportsRecursiveCTE() {
return getVersion().isSameOrAfter( 1, 4, 196 );
return true;
}
@Override
public boolean supportsFetchClause(FetchClauseType type) {
return getVersion().isSameOrAfter( 1, 4, 198 );
return true;
}
@Override
@ -843,9 +784,7 @@ public class H2Dialect extends Dialect {
@Override
public IdentityColumnSupport getIdentityColumnSupport() {
return getVersion().isSameOrAfter( 2 )
? H2FinalTableIdentityColumnSupport.INSTANCE
: H2IdentityColumnSupport.INSTANCE;
return H2FinalTableIdentityColumnSupport.INSTANCE;
}
/**
@ -853,7 +792,7 @@ public class H2Dialect extends Dialect {
*/
@Override
public boolean supportsInsertReturning() {
return getVersion().isSameOrAfter( 2 );
return true;
}
@Override
@ -868,20 +807,14 @@ public class H2Dialect extends Dialect {
@Override
public void appendDatetimeFormat(SqlAppender appender, String format) {
if ( getVersion().isSame( 1, 4, 200 ) ) {
// See https://github.com/h2database/h2database/issues/2518
appender.appendSql( OracleDialect.datetimeFormat( format, true, true ).result() );
}
else {
appender.appendSql(
new Replacer( format, "'", "''" )
.replace("e", "u")
.replace( "xxx", "XXX" )
.replace( "xx", "XX" )
.replace( "x", "X" )
.result()
);
}
appender.appendSql(
new Replacer( format, "'", "''" )
.replace("e", "u")
.replace( "xxx", "XXX" )
.replace( "xx", "XX" )
.replace( "x", "X" )
.result()
);
}
public String translateExtractField(TemporalUnit unit) {

View File

@ -12,7 +12,6 @@ import org.hibernate.LockMode;
import org.hibernate.dialect.identity.H2IdentityColumnSupport;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.sqm.ComparisonOperator;
import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.Statement;
@ -23,13 +22,11 @@ import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.Literal;
import org.hibernate.sql.ast.tree.expression.SqlTuple;
import org.hibernate.sql.ast.tree.expression.SqlTupleContainer;
import org.hibernate.sql.ast.tree.expression.Summarization;
import org.hibernate.sql.ast.tree.from.QueryPartTableReference;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.predicate.BooleanExpressionPredicate;
import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate;
import org.hibernate.sql.ast.tree.predicate.LikePredicate;
import org.hibernate.sql.ast.tree.select.QueryPart;
import org.hibernate.sql.ast.tree.select.SelectClause;
@ -116,12 +113,12 @@ public class H2SqlAstTranslator<T extends JdbcOperation> extends SqlAstTranslato
@Override
protected boolean supportsRowConstructor() {
return getDialect().getVersion().isSameOrAfter( 2 );
return true;
}
@Override
protected boolean supportsArrayConstructor() {
return getDialect().getVersion().isSameOrAfter( 2 );
return true;
}
@Override
@ -175,28 +172,6 @@ public class H2SqlAstTranslator<T extends JdbcOperation> extends SqlAstTranslato
emulateSelectTupleComparison( lhsExpressions, tuple.getExpressions(), operator, true );
}
@Override
public void visitInSubQueryPredicate(InSubQueryPredicate inSubQueryPredicate) {
final SqlTuple lhsTuple;
// As of 1.4.200 this is supported
if ( getDialect().getVersion().isBefore( 1, 4, 200 )
&& ( lhsTuple = SqlTupleContainer.getSqlTuple( inSubQueryPredicate.getTestExpression() ) ) != null
&& lhsTuple.getExpressions().size() != 1 ) {
inSubQueryPredicate.getTestExpression().accept( this );
if ( inSubQueryPredicate.isNegated() ) {
appendSql( " not" );
}
appendSql( " in" );
final boolean renderAsArray = this.renderAsArray;
this.renderAsArray = true;
inSubQueryPredicate.getSubQuery().accept( this );
this.renderAsArray = renderAsArray;
}
else {
super.visitInSubQueryPredicate( inSubQueryPredicate );
}
}
@Override
protected void visitSqlSelections(SelectClause selectClause) {
final boolean renderAsArray = this.renderAsArray;
@ -282,14 +257,13 @@ public class H2SqlAstTranslator<T extends JdbcOperation> extends SqlAstTranslato
@Override
protected boolean supportsRowValueConstructorDistinctFromSyntax() {
// Seems that before, this was buggy
return getDialect().getVersion().isSameOrAfter( 1, 4, 200 );
return true;
}
@Override
protected boolean supportsNullPrecedence() {
// Support for nulls clause in listagg was added in 2.0
return getClauseStack().getCurrent() != Clause.WITHIN_GROUP || getDialect().getVersion().isSameOrAfter( 2 );
return true;
}
@Override
@ -305,6 +279,6 @@ public class H2SqlAstTranslator<T extends JdbcOperation> extends SqlAstTranslato
private boolean supportsOffsetFetchClausePercentWithTies() {
// Introduction of TIES clause https://github.com/h2database/h2database/commit/876e9fbe7baf11d01675bfe871aac2cf1b6104ce
// Introduction of PERCENT support https://github.com/h2database/h2database/commit/f45913302e5f6ad149155a73763c0c59d8205849
return getDialect().getVersion().isSameOrAfter( 1, 4, 198 );
return true;
}
}

View File

@ -50,7 +50,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
settingProviders = @SettingProvider( provider = MultiLoadSubSelectCollectionDialectWithLimitTest.TestSettingProvider.class, settingName = AvailableSettings.DIALECT)
)
@SessionFactory(generateStatistics = true, useCollectingStatementInspector = true)
@RequiresDialect( value = H2Dialect.class, majorVersion = 2 )
@RequiresDialect( value = H2Dialect.class )
public class MultiLoadSubSelectCollectionDialectWithLimitTest {

View File

@ -171,8 +171,8 @@ public class BasicContributorTests {
assertThat(
targetDescriptor.getCommands(),
CollectionElementMatcher.hasAllOf(
CaseInsensitiveStartsWithMatcher.startsWith( "drop table main_table" ),
CaseInsensitiveStartsWithMatcher.startsWith( "drop table DynamicEntity" )
CaseInsensitiveStartsWithMatcher.startsWith( "drop table if exists main_table" ),
CaseInsensitiveStartsWithMatcher.startsWith( "drop table if exists DynamicEntity" )
)
);

View File

@ -52,7 +52,7 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
@Setting(name = AvailableSettings.FORMAT_SQL, value = "false")
}
)
@RequiresDialect(value = H2Dialect.class, majorVersion = 2, comment = "H2 didn't support SQL arrays before version 2")
@RequiresDialect(value = H2Dialect.class)
@JiraKey("HHH-16469")
public class DepthOneBatchTest {

View File

@ -49,7 +49,7 @@ import static org.junit.jupiter.api.Assertions.fail;
}
)
@SessionFactory()
@RequiresDialect( value = H2Dialect.class, majorVersion = 2 )
@RequiresDialect( value = H2Dialect.class )
@JiraKey(value = "HHH-16868")
public class FetchSizeTest {
private PreparedStatementSpyConnectionProvider connectionProvider;

View File

@ -39,7 +39,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
settings = { @Setting(name=AvailableSettings.STATEMENT_BATCH_SIZE, value = "60") }
)
@SessionFactory()
@RequiresDialect( value = H2Dialect.class, majorVersion = 2 )
@RequiresDialect( value = H2Dialect.class )
@JiraKey(value = "HHH-16868")
public class InExpressionCountLimitExceededTest {

View File

@ -63,7 +63,7 @@ public class StandardForeignKeyExporterTest {
sqlStringGenerationContext
);
assertEquals( sqlCreateStrings.length, 1 );
assertEquals( sqlCreateStrings[0], "alter table PERSON add constraint fk_firstLastName foreign key (pkFirstName, pkLastName) references PERSON" );
assertEquals( sqlCreateStrings[0], "alter table if exists PERSON add constraint fk_firstLastName foreign key (pkFirstName, pkLastName) references PERSON" );
}
}

View File

@ -33,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@SessionFactory
@DomainModel( annotatedClasses = { H2JsonListTest.Path.class, H2JsonListTest.PathClob.class } )
@RequiresDialect( value = H2Dialect.class, majorVersion = 2 )
@RequiresDialect( value = H2Dialect.class )
@Jira( "https://hibernate.atlassian.net/browse/HHH-16320" )
public class H2JsonListTest {
@BeforeAll

View File

@ -420,7 +420,7 @@ abstract public class DialectFeatureChecks {
public static class SupportsInverseDistributionFunctions implements DialectFeatureCheck {
public boolean apply(Dialect dialect) {
dialect = DialectDelegateWrapper.extractRealDialect( dialect );
return dialect instanceof H2Dialect && dialect.getVersion().isSameOrAfter( 1, 4, 200 )
return dialect instanceof H2Dialect
|| dialect instanceof PostgreSQLDialect
|| dialect instanceof AbstractHANADialect
|| dialect instanceof CockroachDialect
@ -434,7 +434,7 @@ abstract public class DialectFeatureChecks {
public static class SupportsHypotheticalSetFunctions implements DialectFeatureCheck {
public boolean apply(Dialect dialect) {
dialect = DialectDelegateWrapper.extractRealDialect( dialect );
return dialect instanceof H2Dialect && dialect.getVersion().isSameOrAfter( 1, 4, 200 )
return dialect instanceof H2Dialect
|| dialect instanceof PostgreSQLDialect
|| dialect instanceof AbstractHANADialect
|| dialect instanceof CockroachDialect

View File

@ -27,7 +27,6 @@ helper.runWithNotification {
stage('Configure') {
this.environments = [
// Minimum supported versions
new BuildEnvironment( dbName: 'h2_1_4' ),
new BuildEnvironment( dbName: 'hsqldb_2_6' ),
new BuildEnvironment( dbName: 'derby_10_14' ),
new BuildEnvironment( dbName: 'mysql_5_7' ),
@ -110,10 +109,6 @@ stage('Build') {
try {
stage('Start database') {
switch (buildEnv.dbName) {
case "h2_1_4":
state[buildEnv.tag]['additionalOptions'] = state[buildEnv.tag]['additionalOptions'] +
" -Pgradle.libs.versions.h2=1.4.197 -Pgradle.libs.versions.h2gis=1.5.0"
break;
case "hsqldb_2_6":
state[buildEnv.tag]['additionalOptions'] = state[buildEnv.tag]['additionalOptions'] +
" -Pgradle.libs.versions.hsqldb=2.6.1"

149198
tq Normal file

File diff suppressed because it is too large Load Diff