HHH-16113 - Add version checks for MERGE support to dialects

This commit is contained in:
Steve Ebersole 2023-01-27 22:19:39 -06:00
parent 9883459514
commit 1b2fd1f8a2
2 changed files with 65 additions and 1 deletions

View File

@ -63,6 +63,7 @@ import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationOperation;
import org.hibernate.sql.model.internal.OptionalTableUpdate; 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.SequenceInformationExtractorH2DatabaseImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl; import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor; import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
@ -119,6 +120,8 @@ public class H2Dialect extends Dialect {
private final String querySequenceString; private final String querySequenceString;
private final UniqueDelegate uniqueDelegate = new CreateTableUniqueDelegate(this); private final UniqueDelegate uniqueDelegate = new CreateTableUniqueDelegate(this);
private final OptionalTableUpdateStrategy optionalTableUpdateStrategy;
public H2Dialect(DialectResolutionInfo info) { public H2Dialect(DialectResolutionInfo info) {
this( parseVersion( info ) ); this( parseVersion( info ) );
registerKeywords( info ); registerKeywords( info );
@ -146,6 +149,10 @@ public class H2Dialect extends Dialect {
? SequenceInformationExtractorLegacyImpl.INSTANCE ? SequenceInformationExtractorLegacyImpl.INSTANCE
: SequenceInformationExtractorH2DatabaseImpl.INSTANCE; : SequenceInformationExtractorH2DatabaseImpl.INSTANCE;
this.querySequenceString = "select * from INFORMATION_SCHEMA.SEQUENCES"; this.querySequenceString = "select * from INFORMATION_SCHEMA.SEQUENCES";
this.optionalTableUpdateStrategy = version.isSameOrAfter( 1, 4, 200 )
? H2Dialect::usingMerge
: H2Dialect::withoutMerge;
} }
private static DatabaseVersion parseVersion(DialectResolutionInfo info) { private static DatabaseVersion parseVersion(DialectResolutionInfo info) {
@ -871,12 +878,34 @@ public class H2Dialect extends Dialect {
return BIGINT; return BIGINT;
} }
@FunctionalInterface
private interface OptionalTableUpdateStrategy {
MutationOperation buildMutationOperation(
EntityMutationTarget mutationTarget,
OptionalTableUpdate optionalTableUpdate,
SessionFactoryImplementor factory);
}
@Override @Override
public MutationOperation createOptionalTableUpdateOperation( public MutationOperation createOptionalTableUpdateOperation(
EntityMutationTarget mutationTarget, EntityMutationTarget mutationTarget,
OptionalTableUpdate optionalTableUpdate, OptionalTableUpdate optionalTableUpdate,
SessionFactoryImplementor factory) { SessionFactoryImplementor factory) {
return optionalTableUpdateStrategy.buildMutationOperation( mutationTarget, optionalTableUpdate, factory );
}
private static MutationOperation usingMerge(
EntityMutationTarget mutationTarget,
OptionalTableUpdate optionalTableUpdate,
SessionFactoryImplementor factory) {
final H2SqlAstTranslator<?> translator = new H2SqlAstTranslator<>( factory, optionalTableUpdate ); final H2SqlAstTranslator<?> translator = new H2SqlAstTranslator<>( factory, optionalTableUpdate );
return translator.createMergeOperation( optionalTableUpdate ); return translator.createMergeOperation( optionalTableUpdate );
} }
private static MutationOperation withoutMerge(
EntityMutationTarget mutationTarget,
OptionalTableUpdate optionalTableUpdate,
SessionFactoryImplementor factory) {
return new OptionalTableUpdateOperation( mutationTarget, optionalTableUpdate, factory );
}
} }

View File

@ -71,6 +71,7 @@ import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.sql.model.MutationOperation; import org.hibernate.sql.model.MutationOperation;
import org.hibernate.sql.model.internal.OptionalTableUpdate; import org.hibernate.sql.model.internal.OptionalTableUpdate;
import org.hibernate.sql.model.jdbc.OptionalTableUpdateOperation;
import org.hibernate.type.JavaObjectType; import org.hibernate.type.JavaObjectType;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType; import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
import org.hibernate.type.descriptor.jdbc.AggregateJdbcType; import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
@ -136,10 +137,12 @@ import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithM
*/ */
public class PostgreSQLDialect extends Dialect { public class PostgreSQLDialect extends Dialect {
private final static DatabaseVersion MINIMUM_VERSION = DatabaseVersion.make( 10 ); private final static DatabaseVersion MINIMUM_VERSION = DatabaseVersion.make( 10 );
private static final PostgreSQLIdentityColumnSupport IDENTITY_COLUMN_SUPPORT = new PostgreSQLIdentityColumnSupport(); private static final PostgreSQLIdentityColumnSupport IDENTITY_COLUMN_SUPPORT = new PostgreSQLIdentityColumnSupport();
private final UniqueDelegate uniqueDelegate = new CreateTableUniqueDelegate(this);
private final PostgreSQLDriverKind driverKind; private final PostgreSQLDriverKind driverKind;
private final UniqueDelegate uniqueDelegate = new CreateTableUniqueDelegate(this); private final OptionalTableUpdateStrategy optionalTableUpdateStrategy;
public PostgreSQLDialect() { public PostgreSQLDialect() {
this( MINIMUM_VERSION ); this( MINIMUM_VERSION );
@ -148,16 +151,25 @@ public class PostgreSQLDialect extends Dialect {
public PostgreSQLDialect(DialectResolutionInfo info) { public PostgreSQLDialect(DialectResolutionInfo info) {
super(info); super(info);
driverKind = PostgreSQLDriverKind.determineKind( info ); driverKind = PostgreSQLDriverKind.determineKind( info );
optionalTableUpdateStrategy = determineOptionalTableUpdateStrategy( info );
}
private static OptionalTableUpdateStrategy determineOptionalTableUpdateStrategy(DatabaseVersion version) {
return version.isSameOrAfter( DatabaseVersion.make( 15, 0 ) )
? PostgreSQLDialect::usingMerge
: PostgreSQLDialect::withoutMerge;
} }
public PostgreSQLDialect(DatabaseVersion version) { public PostgreSQLDialect(DatabaseVersion version) {
super(version); super(version);
driverKind = PostgreSQLDriverKind.PG_JDBC; driverKind = PostgreSQLDriverKind.PG_JDBC;
optionalTableUpdateStrategy = determineOptionalTableUpdateStrategy( version );
} }
public PostgreSQLDialect(DatabaseVersion version, PostgreSQLDriverKind driverKind) { public PostgreSQLDialect(DatabaseVersion version, PostgreSQLDriverKind driverKind) {
super(version); super(version);
this.driverKind = driverKind; this.driverKind = driverKind;
optionalTableUpdateStrategy = determineOptionalTableUpdateStrategy( version );
} }
@Override @Override
@ -1376,12 +1388,35 @@ public class PostgreSQLDialect extends Dialect {
return OTHER; return OTHER;
} }
@FunctionalInterface
private interface OptionalTableUpdateStrategy {
MutationOperation buildMutationOperation(
EntityMutationTarget mutationTarget,
OptionalTableUpdate optionalTableUpdate,
SessionFactoryImplementor factory);
}
@Override @Override
public MutationOperation createOptionalTableUpdateOperation( public MutationOperation createOptionalTableUpdateOperation(
EntityMutationTarget mutationTarget, EntityMutationTarget mutationTarget,
OptionalTableUpdate optionalTableUpdate, OptionalTableUpdate optionalTableUpdate,
SessionFactoryImplementor factory) { SessionFactoryImplementor factory) {
return optionalTableUpdateStrategy.buildMutationOperation( mutationTarget, optionalTableUpdate, factory );
}
private static MutationOperation usingMerge(
EntityMutationTarget mutationTarget,
OptionalTableUpdate optionalTableUpdate,
SessionFactoryImplementor factory) {
final PostgreSQLSqlAstTranslator<?> translator = new PostgreSQLSqlAstTranslator<>( factory, optionalTableUpdate ); final PostgreSQLSqlAstTranslator<?> translator = new PostgreSQLSqlAstTranslator<>( factory, optionalTableUpdate );
return translator.createMergeOperation( optionalTableUpdate ); return translator.createMergeOperation( optionalTableUpdate );
} }
private static MutationOperation withoutMerge(
EntityMutationTarget mutationTarget,
OptionalTableUpdate optionalTableUpdate,
SessionFactoryImplementor factory) {
return new OptionalTableUpdateOperation( mutationTarget, optionalTableUpdate, factory );
}
} }