HHH-15812 Firebird dialect improvements
This commit is contained in:
parent
0745a2e294
commit
9290f8b754
|
@ -24,6 +24,7 @@ import jakarta.persistence.TypedQuery;
|
|||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.community.dialect.FirebirdDialect;
|
||||
import org.hibernate.dialect.CockroachDialect;
|
||||
import org.hibernate.dialect.DerbyDialect;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
|
@ -1536,6 +1537,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
|
|||
@Test
|
||||
@SkipForDialect(dialectClass = DerbyDialect.class)
|
||||
@SkipForDialect(dialectClass = SybaseASEDialect.class)
|
||||
@SkipForDialect(dialectClass = FirebirdDialect.class, reason = "order by not supported in list")
|
||||
public void test_hql_aggregate_functions_within_group_example() {
|
||||
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||
//tag::hql-aggregate-functions-within-group-example[]
|
||||
|
|
|
@ -15,6 +15,7 @@ import jakarta.persistence.Table;
|
|||
|
||||
import org.hibernate.annotations.Subselect;
|
||||
import org.hibernate.annotations.Synchronize;
|
||||
import org.hibernate.community.dialect.FirebirdDialect;
|
||||
import org.hibernate.dialect.DerbyDialect;
|
||||
import org.hibernate.dialect.SybaseASEDialect;
|
||||
|
||||
|
@ -39,6 +40,7 @@ import static org.junit.Assert.assertEquals;
|
|||
)
|
||||
@SkipForDialect(dialectClass = DerbyDialect.class, reason = "Derby doesn't support a CONCAT function")
|
||||
@SkipForDialect(dialectClass = SybaseASEDialect.class, reason = "Sybase doesn't support a CONCAT function")
|
||||
@SkipForDialect(dialectClass = FirebirdDialect.class, reason = "Firebird doesn't support a CONCAT function")
|
||||
public class SubselectTest {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -82,6 +82,7 @@ public class TimeZoneStorageMappingTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsFormat.class)
|
||||
public void testOffsetRetainedAuto(SessionFactoryScope scope) {
|
||||
testOffsetRetained( scope, "Auto" );
|
||||
}
|
||||
|
|
|
@ -205,14 +205,14 @@ ext {
|
|||
'connection.init_sql' : ''
|
||||
],
|
||||
firebird : [
|
||||
'db.dialect' : 'org.hibernate.dialect.FirebirdDialect',
|
||||
'db.dialect' : 'org.hibernate.community.dialect.FirebirdDialect',
|
||||
'jdbc.driver': 'org.firebirdsql.jdbc.FBDriver',
|
||||
'jdbc.user' : 'sysdba',
|
||||
'jdbc.pass' : 'masterkey',
|
||||
// Overriding default transaction definition (5 seconds instead of infinite wait) to prevent problems in test cleanup
|
||||
// Expects alias 'hibernate_orm_test' in aliases.conf (FB2.5 and earlier) or databases.conf (FB3.0 and later)
|
||||
// Created database must either use default character set NONE, or UTF8 with page size 16384 or higher (to prevent issues with indexes due to keysize)
|
||||
'jdbc.url' : 'jdbc:firebirdsql://' + dbHost +'localhost/hibernate_orm_test?charSet=utf-8;TRANSACTION_READ_COMMITTED=read_committed,rec_version,wait,lock_timeout=5',
|
||||
'jdbc.url' : 'jdbc:firebirdsql://' + dbHost +'/hibernate_orm_test?charSet=utf-8;TRANSACTION_READ_COMMITTED=read_committed,rec_version,wait,lock_timeout=5',
|
||||
'connection.init_sql' : ''
|
||||
],
|
||||
]
|
||||
|
|
|
@ -109,6 +109,9 @@ dependencies {
|
|||
else if ( db.startsWith( 'mariadb' ) ) {
|
||||
testRuntimeOnly dbLibs.mariadb
|
||||
}
|
||||
else if ( db.startsWith( 'firebird' ) ) {
|
||||
testRuntimeOnly dbLibs.firebird
|
||||
}
|
||||
|
||||
annotationProcessor libs.loggingProcessor
|
||||
annotationProcessor libs.logging
|
||||
|
|
|
@ -82,7 +82,8 @@ public enum CommunityDatabase {
|
|||
}
|
||||
@Override
|
||||
public String getUrlPrefix() {
|
||||
return "jdbc:firebirdsql:";
|
||||
// Jaybird 4 and higher support jdbc:firebird: and jdbc:firebirdsql: as JDBC protocol
|
||||
return "jdbc:firebird";
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -9,15 +9,23 @@ package org.hibernate.community.dialect;
|
|||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.temporal.ChronoField;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.hibernate.boot.Metadata;
|
||||
import org.hibernate.boot.model.TypeContributions;
|
||||
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
|
||||
import org.hibernate.community.dialect.identity.FirebirdIdentityColumnSupport;
|
||||
import org.hibernate.community.dialect.pagination.SkipFirstLimitHandler;
|
||||
import org.hibernate.community.dialect.sequence.FirebirdSequenceSupport;
|
||||
|
@ -26,6 +34,7 @@ import org.hibernate.community.dialect.sequence.SequenceInformationExtractorFire
|
|||
import org.hibernate.dialect.BooleanDecoder;
|
||||
import org.hibernate.dialect.DatabaseVersion;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.NationalizationSupport;
|
||||
import org.hibernate.dialect.TimeZoneSupport;
|
||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||
import org.hibernate.dialect.identity.IdentityColumnSupport;
|
||||
|
@ -44,10 +53,13 @@ import org.hibernate.exception.LockTimeoutException;
|
|||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.mapping.Index;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.CastType;
|
||||
import org.hibernate.query.sqm.FetchClauseType;
|
||||
import org.hibernate.query.sqm.IntervalType;
|
||||
import org.hibernate.query.sqm.NullOrdering;
|
||||
import org.hibernate.query.sqm.TemporalUnit;
|
||||
|
@ -57,6 +69,7 @@ import org.hibernate.query.sqm.mutation.internal.temptable.GlobalTemporaryTableM
|
|||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
|
||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
|
@ -65,9 +78,12 @@ import org.hibernate.sql.ast.tree.Statement;
|
|||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
import org.hibernate.tool.schema.extract.internal.SequenceNameExtractorImpl;
|
||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||
import org.hibernate.tool.schema.internal.StandardIndexExporter;
|
||||
import org.hibernate.tool.schema.spi.Exporter;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.BasicTypeRegistry;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.descriptor.DateTimeUtils;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
||||
import org.hibernate.type.descriptor.sql.internal.BinaryFloatDdlType;
|
||||
|
@ -87,12 +103,8 @@ import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
|
|||
import static org.hibernate.type.SqlTypes.TIME_WITH_TIMEZONE;
|
||||
import static org.hibernate.type.SqlTypes.TINYINT;
|
||||
import static org.hibernate.type.SqlTypes.VARBINARY;
|
||||
import static org.hibernate.type.descriptor.DateTimeUtils.JDBC_ESCAPE_END;
|
||||
import static org.hibernate.type.descriptor.DateTimeUtils.JDBC_ESCAPE_START_DATE;
|
||||
import static org.hibernate.type.descriptor.DateTimeUtils.JDBC_ESCAPE_START_TIME;
|
||||
import static org.hibernate.type.descriptor.DateTimeUtils.JDBC_ESCAPE_START_TIMESTAMP;
|
||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
|
||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
|
||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
|
||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMillis;
|
||||
|
||||
/**
|
||||
|
@ -184,7 +196,7 @@ public class FirebirdDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public int getMaxVarbinaryLength() {
|
||||
return 32_756;
|
||||
return 32_765;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -249,6 +261,12 @@ public class FirebirdDialect extends Dialect {
|
|||
final BasicType<Character> characterType = basicTypeRegistry.resolve( StandardBasicTypes.CHARACTER );
|
||||
|
||||
CommonFunctionFactory functionFactory = new CommonFunctionFactory(queryEngine);
|
||||
|
||||
// Firebird needs an actual argument type for aggregates like SUM, AVG, MIN, MAX to determine the result type
|
||||
functionFactory.aggregates( this, SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER );
|
||||
// AVG by default uses the input type, so we possibly need to cast the argument type, hence a special function
|
||||
functionFactory.avg_castingNonDoubleArguments( this, SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER );
|
||||
|
||||
functionFactory.concat_pipeOperator();
|
||||
functionFactory.cot();
|
||||
functionFactory.cosh();
|
||||
|
@ -511,6 +529,7 @@ public class FirebirdDialect extends Dialect {
|
|||
DatabaseMetaData dbMetaData) throws SQLException {
|
||||
// Any use of keywords as identifiers will result in token unknown error, so enable auto quote always
|
||||
builder.setAutoQuoteKeywords( true );
|
||||
builder.setAutoQuoteInitialUnderscore( true );
|
||||
|
||||
// Additional reserved words
|
||||
// The Hibernate list of SQL:2003 reserved words doesn't contain all SQL:2003 reserved words,
|
||||
|
@ -594,7 +613,7 @@ public class FirebirdDialect extends Dialect {
|
|||
@Override
|
||||
public void appendBooleanValueString(SqlAppender appender, boolean bool) {
|
||||
//'boolean' type introduced in 3.0
|
||||
if ( getVersion().isSameOrAfter( 3, 0 ) ) {
|
||||
if ( getVersion().isBefore( 3 ) ) {
|
||||
appender.appendSql( bool ? '1' : '0' );
|
||||
}
|
||||
else {
|
||||
|
@ -611,14 +630,18 @@ public class FirebirdDialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public SequenceSupport getSequenceSupport() {
|
||||
if ( getVersion().isBefore( 2, 0 ) ) {
|
||||
return InterbaseSequenceSupport.INSTANCE;
|
||||
DatabaseVersion version = getVersion();
|
||||
if ( version.isSameOrAfter( 4 ) ) {
|
||||
return FirebirdSequenceSupport.INSTANCE;
|
||||
}
|
||||
else if ( getVersion().isBefore( 3, 0 ) ) {
|
||||
else if ( version.isSame( 3 ) ) {
|
||||
return FirebirdSequenceSupport.FB3_INSTANCE;
|
||||
}
|
||||
else if ( version.isSame( 2 ) ) {
|
||||
return FirebirdSequenceSupport.LEGACY_INSTANCE;
|
||||
}
|
||||
else {
|
||||
return FirebirdSequenceSupport.INSTANCE;
|
||||
return InterbaseSequenceSupport.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -702,6 +725,11 @@ public class FirebirdDialect extends Dialect {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsFetchClause(FetchClauseType type) {
|
||||
return type == FetchClauseType.ROWS_ONLY && getVersion().isSameOrAfter( 3 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsValuesListForInsert() {
|
||||
return false;
|
||||
|
@ -717,6 +745,38 @@ public class FirebirdDialect extends Dialect {
|
|||
return getVersion().isSameOrAfter( 4, 0 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public NationalizationSupport getNationalizationSupport() {
|
||||
return NationalizationSupport.IMPLICIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsDistinctFromPredicate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsRecursiveCTE() {
|
||||
// Since Firebird 2.1
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsPredicateAsExpression() {
|
||||
return getVersion().isSameOrAfter( 3 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generatedAs(String generatedAs) {
|
||||
return " generated always as (" + generatedAs + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDataTypeBeforeGeneratedAs() {
|
||||
// data type is optional
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String translateExtractField(TemporalUnit unit) {
|
||||
switch ( unit ) {
|
||||
|
@ -734,19 +794,19 @@ public class FirebirdDialect extends Dialect {
|
|||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
case DATE:
|
||||
appender.appendSql( JDBC_ESCAPE_START_DATE );
|
||||
appender.appendSql( "date '" );
|
||||
appendAsDate( appender, temporalAccessor );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
appender.appendSql( '\'' );
|
||||
break;
|
||||
case TIME:
|
||||
appender.appendSql( JDBC_ESCAPE_START_TIME );
|
||||
appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
appender.appendSql( "time '" );
|
||||
FirebirdDateTimeUtils.appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
||||
appender.appendSql( '\'' );
|
||||
break;
|
||||
case TIMESTAMP:
|
||||
appender.appendSql( JDBC_ESCAPE_START_TIMESTAMP );
|
||||
appendAsTimestampWithMillis( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
appender.appendSql( "timestamp '" );
|
||||
FirebirdDateTimeUtils.appendAsTimestampWithMillis( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
||||
appender.appendSql( '\'' );
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
|
@ -756,19 +816,19 @@ public class FirebirdDialect extends Dialect {
|
|||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
case DATE:
|
||||
appender.appendSql( JDBC_ESCAPE_START_DATE );
|
||||
appender.appendSql( "date '" );
|
||||
appendAsDate( appender, date );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
appender.appendSql( '\'' );
|
||||
break;
|
||||
case TIME:
|
||||
appender.appendSql( JDBC_ESCAPE_START_TIME );
|
||||
appendAsTime( appender, date );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
appender.appendSql( "time '" );
|
||||
appendAsLocalTime( appender, date );
|
||||
appender.appendSql( '\'' );
|
||||
break;
|
||||
case TIMESTAMP:
|
||||
appender.appendSql( JDBC_ESCAPE_START_TIMESTAMP );
|
||||
appender.appendSql( "timestamp '" );
|
||||
appendAsTimestampWithMillis( appender, date, jdbcTimeZone );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
appender.appendSql( '\'' );
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
|
@ -782,19 +842,19 @@ public class FirebirdDialect extends Dialect {
|
|||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
case DATE:
|
||||
appender.appendSql( JDBC_ESCAPE_START_DATE );
|
||||
appender.appendSql( "date '" );
|
||||
appendAsDate( appender, calendar );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
appender.appendSql( '\'' );
|
||||
break;
|
||||
case TIME:
|
||||
appender.appendSql( JDBC_ESCAPE_START_TIME );
|
||||
appendAsTime( appender, calendar );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
appender.appendSql( "time '" );
|
||||
appendAsLocalTime( appender, calendar );
|
||||
appender.appendSql( '\'' );
|
||||
break;
|
||||
case TIMESTAMP:
|
||||
appender.appendSql( JDBC_ESCAPE_START_TIMESTAMP );
|
||||
appender.appendSql( "timestamp '" );
|
||||
appendAsTimestampWithMillis( appender, calendar, jdbcTimeZone );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
appender.appendSql( '\'' );
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
|
@ -806,6 +866,13 @@ public class FirebirdDialect extends Dialect {
|
|||
throw new UnsupportedOperationException( "format() function not supported on Firebird" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendUUIDLiteral(SqlAppender appender, UUID literal) {
|
||||
appender.appendSql( "char_to_uuid('" );
|
||||
appender.appendSql( literal.toString() );
|
||||
appender.appendSql( "')" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViolatedConstraintNameExtractor getViolatedConstraintNameExtractor() {
|
||||
return EXTRACTOR;
|
||||
|
@ -930,4 +997,101 @@ public class FirebirdDialect extends Dialect {
|
|||
public String getTemporaryTableCreateOptions() {
|
||||
return "on commit delete rows";
|
||||
}
|
||||
|
||||
private final FirebirdIndexExporter indexExporter = new FirebirdIndexExporter( this );
|
||||
|
||||
@Override
|
||||
public Exporter<Index> getIndexExporter() {
|
||||
return indexExporter;
|
||||
}
|
||||
|
||||
private static class FirebirdIndexExporter extends StandardIndexExporter {
|
||||
|
||||
public FirebirdIndexExporter(Dialect dialect) {
|
||||
super( dialect );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSqlCreateStrings(Index index, Metadata metadata, SqlStringGenerationContext context) {
|
||||
final String tableName = context.format( index.getTable().getQualifiedTableName() );
|
||||
final Dialect dialect = getDialect();
|
||||
final String indexNameForCreation = index.getQuotedName( dialect );
|
||||
// In firebird the index is only sortable on top-level, not per column, use the first column to decide
|
||||
final String sortOrder = index.getColumnOrderMap().getOrDefault( index.getColumns().get( 0 ), "asc" );
|
||||
final StringBuilder buf = new StringBuilder()
|
||||
// Although `create asc index` is valid, generate without (some tests check for a specific syntax prefix)
|
||||
.append( "desc".equalsIgnoreCase( sortOrder ) || "descending".equalsIgnoreCase( sortOrder ) ? "create desc index " : "create index " )
|
||||
.append( indexNameForCreation )
|
||||
.append( " on " )
|
||||
.append( tableName )
|
||||
.append( " (" );
|
||||
boolean first = true;
|
||||
for ( Column column : index.getColumns() ) {
|
||||
if ( first ) {
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
buf.append( ", " );
|
||||
}
|
||||
buf.append( ( column.getQuotedName( dialect ) ) );
|
||||
}
|
||||
buf.append( ')' );
|
||||
|
||||
return new String[] { buf.toString() };
|
||||
}
|
||||
}
|
||||
|
||||
private static final class FirebirdDateTimeUtils {
|
||||
|
||||
// Default formatting of DateTimeUtils renders UTC as Z, while Firebird expects +00:00
|
||||
|
||||
private static final DateTimeFormatter OFFSET_TIME = new DateTimeFormatterBuilder()
|
||||
.parseCaseInsensitive()
|
||||
.append( DateTimeUtils.DATE_TIME_FORMATTER_TIME )
|
||||
.parseLenient()
|
||||
.appendOffset( "+HH:MM", "+00:00" )
|
||||
.parseStrict()
|
||||
.toFormatter( Locale.ENGLISH );
|
||||
|
||||
private static final DateTimeFormatter OFFSET_DATE_TIME_MILLIS = new DateTimeFormatterBuilder()
|
||||
.parseCaseInsensitive()
|
||||
.append( DateTimeUtils.DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS )
|
||||
.parseLenient()
|
||||
.appendOffset( "+HH:MM", "+00:00" )
|
||||
.parseStrict()
|
||||
.toFormatter( Locale.ENGLISH );
|
||||
|
||||
private static void appendAsTime(
|
||||
SqlAppender appender,
|
||||
TemporalAccessor temporalAccessor,
|
||||
boolean supportsOffset,
|
||||
TimeZone jdbcTimeZone) {
|
||||
if ( supportsOffset && temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) {
|
||||
OFFSET_TIME.formatTo( temporalAccessor, appender );
|
||||
}
|
||||
else {
|
||||
DateTimeUtils.appendAsTime( appender, temporalAccessor, supportsOffset, jdbcTimeZone );
|
||||
}
|
||||
}
|
||||
|
||||
public static void appendAsTimestampWithMillis(
|
||||
SqlAppender appender,
|
||||
TemporalAccessor temporalAccessor,
|
||||
boolean supportsOffset,
|
||||
TimeZone jdbcTimeZone) {
|
||||
if ( supportsOffset && temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) {
|
||||
OFFSET_DATE_TIME_MILLIS.formatTo( temporalAccessor, appender );
|
||||
}
|
||||
else if ( supportsOffset && temporalAccessor instanceof Instant ) {
|
||||
OFFSET_DATE_TIME_MILLIS.formatTo(
|
||||
( (Instant) temporalAccessor ).atZone( jdbcTimeZone.toZoneId() ),
|
||||
appender
|
||||
);
|
||||
}
|
||||
else {
|
||||
DateTimeUtils.appendAsTimestampWithMillis( appender, temporalAccessor, supportsOffset, jdbcTimeZone );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,15 +7,19 @@
|
|||
package org.hibernate.community.dialect;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.util.collections.Stack;
|
||||
import org.hibernate.query.sqm.ComparisonOperator;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.Statement;
|
||||
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
|
||||
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.expression.FunctionExpression;
|
||||
import org.hibernate.sql.ast.tree.expression.JdbcLiteral;
|
||||
|
@ -26,6 +30,7 @@ import org.hibernate.sql.ast.tree.expression.SelfRenderingExpression;
|
|||
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
||||
import org.hibernate.sql.ast.tree.expression.Summarization;
|
||||
import org.hibernate.sql.ast.tree.predicate.BooleanExpressionPredicate;
|
||||
import org.hibernate.sql.ast.tree.predicate.InListPredicate;
|
||||
import org.hibernate.sql.ast.tree.predicate.SelfRenderingPredicate;
|
||||
import org.hibernate.sql.ast.tree.select.QueryGroup;
|
||||
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||
|
@ -63,6 +68,58 @@ public class FirebirdSqlAstTranslator<T extends JdbcOperation> extends AbstractS
|
|||
}
|
||||
}
|
||||
|
||||
// Firebird does not allow CASE expressions where all result arms contain plain parameters.
|
||||
// At least one result arm must provide some type context for inference,
|
||||
// so we cast the first result arm if we encounter this condition
|
||||
|
||||
@Override
|
||||
protected void visitAnsiCaseSearchedExpression(
|
||||
CaseSearchedExpression caseSearchedExpression,
|
||||
Consumer<Expression> resultRenderer) {
|
||||
if ( getParameterRenderingMode() == SqlAstNodeRenderingMode.DEFAULT && areAllResultsParameters( caseSearchedExpression ) ) {
|
||||
final List<CaseSearchedExpression.WhenFragment> whenFragments = caseSearchedExpression.getWhenFragments();
|
||||
final Expression firstResult = whenFragments.get( 0 ).getResult();
|
||||
super.visitAnsiCaseSearchedExpression(
|
||||
caseSearchedExpression,
|
||||
e -> {
|
||||
if ( e == firstResult ) {
|
||||
renderCasted( e );
|
||||
}
|
||||
else {
|
||||
resultRenderer.accept( e );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
super.visitAnsiCaseSearchedExpression( caseSearchedExpression, resultRenderer );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void visitAnsiCaseSimpleExpression(
|
||||
CaseSimpleExpression caseSimpleExpression,
|
||||
Consumer<Expression> resultRenderer) {
|
||||
if ( getParameterRenderingMode() == SqlAstNodeRenderingMode.DEFAULT && areAllResultsParameters( caseSimpleExpression ) ) {
|
||||
final List<CaseSimpleExpression.WhenFragment> whenFragments = caseSimpleExpression.getWhenFragments();
|
||||
final Expression firstResult = whenFragments.get( 0 ).getResult();
|
||||
super.visitAnsiCaseSimpleExpression(
|
||||
caseSimpleExpression,
|
||||
e -> {
|
||||
if ( e == firstResult ) {
|
||||
renderCasted( e );
|
||||
}
|
||||
else {
|
||||
resultRenderer.accept( e );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
super.visitAnsiCaseSimpleExpression( caseSimpleExpression, resultRenderer );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getForUpdate() {
|
||||
return " with lock";
|
||||
|
@ -104,6 +161,7 @@ public class FirebirdSqlAstTranslator<T extends JdbcOperation> extends AbstractS
|
|||
try {
|
||||
appendSql( "select " );
|
||||
visitSqlSelections( selectClause );
|
||||
renderVirtualSelections( selectClause );
|
||||
}
|
||||
finally {
|
||||
clauseStack.pop();
|
||||
|
@ -133,9 +191,9 @@ public class FirebirdSqlAstTranslator<T extends JdbcOperation> extends AbstractS
|
|||
|
||||
@Override
|
||||
protected boolean supportsSimpleQueryGrouping() {
|
||||
// Firebird is quite strict i.e. it requires `select .. union all select * from (select ...)`
|
||||
// Firebird 4 and earlier are quite strict i.e. it requires `select .. union all select * from (select ...)`
|
||||
// rather than `select .. union all (select ...)`
|
||||
return false;
|
||||
return getDialect().getVersion().isSameOrAfter( 5 );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -167,6 +225,28 @@ public class FirebirdSqlAstTranslator<T extends JdbcOperation> extends AbstractS
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInListPredicate(InListPredicate inListPredicate) {
|
||||
final List<Expression> listExpressions = inListPredicate.getListExpressions();
|
||||
if ( listExpressions.isEmpty() ) {
|
||||
appendSql( "1=0" );
|
||||
return;
|
||||
}
|
||||
final Expression testExpression = inListPredicate.getTestExpression();
|
||||
if ( isParameter( testExpression ) ) {
|
||||
renderCasted( testExpression );
|
||||
if ( inListPredicate.isNegated() ) {
|
||||
appendSql( " not" );
|
||||
}
|
||||
appendSql( " in(" );
|
||||
renderCommaSeparated( listExpressions );
|
||||
appendSql( CLOSE_PARENTHESIS );
|
||||
}
|
||||
else {
|
||||
super.visitInListPredicate( inListPredicate );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsRowValueConstructorSyntax() {
|
||||
return false;
|
||||
|
@ -196,6 +276,16 @@ public class FirebirdSqlAstTranslator<T extends JdbcOperation> extends AbstractS
|
|||
return getDialect().getVersion().isSameOrAfter( 3 );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsIntersect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsNestedWithClause() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSelfRenderingPredicate(SelfRenderingPredicate selfRenderingPredicate) {
|
||||
// see comments in visitParameter
|
||||
|
@ -213,9 +303,9 @@ public class FirebirdSqlAstTranslator<T extends JdbcOperation> extends AbstractS
|
|||
public void visitSelfRenderingExpression(SelfRenderingExpression expression) {
|
||||
// see comments in visitParameter
|
||||
boolean inFunction = this.inFunction;
|
||||
this.inFunction = !( expression instanceof FunctionExpression ) || !"cast".equals( ( (FunctionExpression) expression).getFunctionName() );
|
||||
this.inFunction = !( expression instanceof FunctionExpression ) || !"cast".equals( ( (FunctionExpression) expression ).getFunctionName() );
|
||||
try {
|
||||
super.visitSelfRenderingExpression( expression);
|
||||
super.visitSelfRenderingExpression( expression );
|
||||
}
|
||||
finally {
|
||||
this.inFunction = inFunction;
|
||||
|
|
|
@ -18,14 +18,14 @@ import org.hibernate.dialect.sequence.SequenceSupport;
|
|||
*/
|
||||
public class FirebirdSequenceSupport extends ANSISequenceSupport {
|
||||
|
||||
public static final SequenceSupport INSTANCE = new FirebirdSequenceSupport() {
|
||||
public static final SequenceSupport INSTANCE = new FirebirdSequenceSupport();
|
||||
|
||||
public static final SequenceSupport FB3_INSTANCE = new FirebirdSequenceSupport() {
|
||||
@Override
|
||||
public String getCreateSequenceString(String sequenceName, int initialValue, int incrementSize) {
|
||||
// NOTE Firebird 3 has an 'off by increment' bug, see
|
||||
// http://tracker.firebirdsql.org/browse/CORE-6084
|
||||
// NOTE Firebird 3 has an 'off by increment' bug, see https://github.com/FirebirdSQL/firebird/issues/6334
|
||||
if (initialValue == 1 && incrementSize == 1) {
|
||||
// Workaround for initial value and increment 1
|
||||
// This workaround also works fine in Firebird 4, so we don't need to add yet another specialization
|
||||
return getCreateSequenceString( sequenceName );
|
||||
}
|
||||
return super.getCreateSequenceString( sequenceName, initialValue, incrementSize);
|
||||
|
|
|
@ -60,8 +60,11 @@ public class LoadFetchGraphWithEagerSelfReferencingEagerToOneTest {
|
|||
@AfterEach
|
||||
public void tearDown(EntityManagerFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
entityManager ->
|
||||
entityManager.createQuery( "delete from Sample" ).executeUpdate()
|
||||
entityManager -> {
|
||||
entityManager.createQuery( "delete from Sample where id = 1" ).executeUpdate();
|
||||
entityManager.createQuery( "delete from Sample where id = 2" ).executeUpdate();
|
||||
entityManager.createQuery( "delete from Sample where id = 3" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.hibernate.annotations.Filter;
|
|||
import org.hibernate.annotations.FilterDef;
|
||||
import org.hibernate.annotations.JdbcTypeCode;
|
||||
import org.hibernate.annotations.ParamDef;
|
||||
import org.hibernate.community.dialect.FirebirdDialect;
|
||||
import org.hibernate.dialect.AbstractHANADialect;
|
||||
import org.hibernate.dialect.CockroachDialect;
|
||||
import org.hibernate.dialect.DB2Dialect;
|
||||
|
@ -83,6 +84,7 @@ public class FilterParameterTests {
|
|||
@SkipForDialect(dialectClass = AbstractHANADialect.class, matchSubTypes = true, reason = "HANA silently converts a boolean to string types")
|
||||
@SkipForDialect(dialectClass = CockroachDialect.class, matchSubTypes = true, reason = "Cockroach silently converts a boolean to string types")
|
||||
@SkipForDialect(dialectClass = PostgresPlusDialect.class, reason = "PostgresPlus silently converts a boolean to string types")
|
||||
@SkipForDialect(dialectClass = FirebirdDialect.class, reason = "Firebird silently converts a boolean to string")
|
||||
public void testYesNoMismatch(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
final EntityOne loaded = session.byId( EntityOne.class ).load( 1 );
|
||||
|
@ -129,6 +131,7 @@ public class FilterParameterTests {
|
|||
@SkipForDialect(dialectClass = SQLServerDialect.class, reason = "SQL Server silently converts a boolean to integral types")
|
||||
@SkipForDialect(dialectClass = SybaseDialect.class, matchSubTypes = true, reason = "Sybase silently converts a boolean to integral types")
|
||||
@SkipForDialect(dialectClass = AbstractHANADialect.class, matchSubTypes = true, reason = "HANA silently converts a boolean to integral types")
|
||||
@SkipForDialect(dialectClass = FirebirdDialect.class, matchSubTypes = true, reason = "Firebird silently converts a boolean to integral types")
|
||||
public void testNumericMismatch(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
final EntityTwo loaded = session.byId( EntityTwo.class ).load( 1 );
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
package org.hibernate.orm.test.hbm.collectionpk;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.hibernate.boot.Metadata;
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
|
@ -44,11 +46,12 @@ public class CollectionPkTest extends BaseUnitTestCase {
|
|||
public void testSet() {
|
||||
verifyPkNameUsed(
|
||||
"org/hibernate/orm/test/hbm/collectionpk/person_set.hbm.xml",
|
||||
"primary key (group, name)"
|
||||
"primary key (group, name)",
|
||||
"primary key (\"group\", name)"
|
||||
);
|
||||
}
|
||||
|
||||
private void verifyPkNameUsed(String mappingResource, String expectedName) {
|
||||
private void verifyPkNameUsed(String mappingResource, String... expectedName) {
|
||||
final Metadata metadata = new MetadataSources( ssr )
|
||||
.addResource( mappingResource )
|
||||
.buildMetadata();
|
||||
|
@ -57,8 +60,8 @@ public class CollectionPkTest extends BaseUnitTestCase {
|
|||
new SchemaCreatorImpl( ssr ).doCreation( metadata, false, target );
|
||||
|
||||
assertTrue(
|
||||
"Expected foreign-key name [" + expectedName + "] not seen in schema creation output",
|
||||
target.containedText( expectedName )
|
||||
"Expected foreign-key name [" + Arrays.toString(expectedName) + "] not seen in schema creation output",
|
||||
Arrays.stream( expectedName ).anyMatch( target::containedText )
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -66,7 +69,8 @@ public class CollectionPkTest extends BaseUnitTestCase {
|
|||
public void testMap() {
|
||||
verifyPkNameUsed(
|
||||
"org/hibernate/orm/test/hbm/collectionpk/person_map.hbm.xml",
|
||||
"primary key (group, locale)"
|
||||
"primary key (group, locale)",
|
||||
"primary key (\"group\", locale)"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,12 +48,15 @@ public class NonUniqueIdTest {
|
|||
session.createNativeQuery(
|
||||
"create table CATEGORY( id integer not null, name varchar(255) )"
|
||||
).executeUpdate();
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createNativeQuery( "insert into CATEGORY( id, name) VALUES( 1, 'clothes' )" )
|
||||
.executeUpdate();
|
||||
session.createNativeQuery( "insert into CATEGORY( id, name) VALUES( 1, 'shoes' )" )
|
||||
.executeUpdate();
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.sql.Statement;
|
|||
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.dialect.DerbyDialect;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
|
@ -59,6 +60,7 @@ public class BasicConnectionTest extends BaseCoreFunctionalTestCase {
|
|||
JdbcCoordinator jdbcCoord = sessionImpl.getJdbcCoordinator();
|
||||
|
||||
try {
|
||||
Transaction ddlTxn = session.beginTransaction();
|
||||
Statement statement = jdbcCoord.getStatementPreparer().createStatement();
|
||||
String dropSql = sessionFactory().getJdbcServices().getDialect().getDropTableString( "SANDBOX_JDBC_TST" );
|
||||
try {
|
||||
|
@ -74,6 +76,7 @@ public class BasicConnectionTest extends BaseCoreFunctionalTestCase {
|
|||
getResourceRegistry( jdbcCoord ).release( statement );
|
||||
assertFalse( getResourceRegistry( jdbcCoord ).hasRegisteredResources() );
|
||||
assertTrue( jdbcCoord.getLogicalConnection().isPhysicallyConnected() ); // after_transaction specified
|
||||
ddlTxn.commit();
|
||||
|
||||
PreparedStatement ps = jdbcCoord.getStatementPreparer().prepareStatement(
|
||||
"insert into SANDBOX_JDBC_TST( ID, NAME ) values ( ?, ? )" );
|
||||
|
|
|
@ -302,6 +302,7 @@ public class BatchingTest extends BaseCoreFunctionalTestCase implements BatchKey
|
|||
}
|
||||
|
||||
private void exportSandboxSchema(SessionImplementor sessionImpl) {
|
||||
Transaction txn = sessionImpl.beginTransaction();
|
||||
final JdbcCoordinator jdbcCoordinator = sessionImpl.getJdbcCoordinator();
|
||||
LogicalConnectionImplementor logicalConnection = jdbcCoordinator.getLogicalConnection();
|
||||
|
||||
|
@ -320,6 +321,7 @@ public class BatchingTest extends BaseCoreFunctionalTestCase implements BatchKey
|
|||
jdbcCoordinator.getLogicalConnection().getResourceRegistry().release( statement );
|
||||
assertFalse( jdbcCoordinator.getLogicalConnection().getResourceRegistry().hasRegisteredResources() );
|
||||
assertTrue( logicalConnection.isPhysicallyConnected() ); // after_transaction specified
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.hibernate.LockOptions;
|
|||
import org.hibernate.Session;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.community.dialect.FirebirdDialect;
|
||||
import org.hibernate.dialect.AbstractHANADialect;
|
||||
import org.hibernate.dialect.CockroachDialect;
|
||||
import org.hibernate.dialect.DerbyDialect;
|
||||
|
@ -1175,6 +1176,7 @@ public class LockTest extends BaseEntityManagerFunctionalTestCase {
|
|||
@SkipForDialect(value = HSQLDialect.class, comment = "Seems like FK constraint checks are not compatible with exclusive locks")
|
||||
@SkipForDialect(value = AbstractHANADialect.class, comment = "Seems like FK constraint checks are not compatible with exclusive locks")
|
||||
@SkipForDialect(value = CockroachDialect.class, comment = "Cockroach supports the 'for no key update' syntax but it doesn't work")
|
||||
@SkipForDialect(value = FirebirdDialect.class, comment = "Seems like FK constraint checks are not compatible with exclusive locks")
|
||||
public void testLockInsertFkTarget() {
|
||||
Lock lock = new Lock();
|
||||
lock.setName( "name" );
|
||||
|
@ -1212,6 +1214,7 @@ public class LockTest extends BaseEntityManagerFunctionalTestCase {
|
|||
@SkipForDialect(value = HSQLDialect.class, comment = "Seems like FK constraint checks are not compatible with exclusive locks")
|
||||
@SkipForDialect(value = AbstractHANADialect.class, comment = "Seems like FK constraint checks are not compatible with exclusive locks")
|
||||
@SkipForDialect(value = CockroachDialect.class, comment = "Cockroach supports the 'for no key update' syntax but it doesn't work")
|
||||
@SkipForDialect(value = FirebirdDialect.class, comment = "Seems like FK constraint checks are not compatible with exclusive locks")
|
||||
public void testLockUpdateFkTarget() {
|
||||
Lock lock1 = new Lock();
|
||||
lock1.setName( "l1" );
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.hibernate.Session;
|
|||
import org.hibernate.annotations.JdbcTypeCode;
|
||||
import org.hibernate.annotations.Nationalized;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.community.dialect.FirebirdDialect;
|
||||
import org.hibernate.dialect.AbstractHANADialect;
|
||||
import org.hibernate.dialect.AbstractTransactSQLDialect;
|
||||
import org.hibernate.dialect.CockroachDialect;
|
||||
|
@ -149,6 +150,7 @@ public class NativeQueryResultTypeAutoDiscoveryTest {
|
|||
@SkipForDialect(dialectClass = AbstractTransactSQLDialect.class, matchSubTypes = true, reason = "No support for the tinyint datatype so we use smallint")
|
||||
@SkipForDialect(dialectClass = AbstractHANADialect.class, matchSubTypes = true, reason = "No support for the tinyint datatype so we use smallint")
|
||||
@SkipForDialect(dialectClass = OracleDialect.class, reason = "Oracle maps tinyint to number")
|
||||
@SkipForDialect(dialectClass = FirebirdDialect.class, reason = "No support for the tinyint datatype so we use smallint")
|
||||
public void tinyintType() {
|
||||
createEntityManagerFactory( TinyintEntity.class );
|
||||
doTest( TinyintEntity.class, (byte)127 );
|
||||
|
@ -178,6 +180,7 @@ public class NativeQueryResultTypeAutoDiscoveryTest {
|
|||
@SkipForDialect(dialectClass = OracleDialect.class, reason = "Value is too big for the maximum allowed precision of Oracle")
|
||||
@SkipForDialect(dialectClass = AbstractTransactSQLDialect.class, matchSubTypes = true, reason = "Value is too big for the maximum allowed precision of SQL Server and Sybase")
|
||||
@SkipForDialect(dialectClass = AbstractHANADialect.class, matchSubTypes = true, reason = "Value is too big for the maximum allowed precision of HANA")
|
||||
@SkipForDialect(dialectClass = FirebirdDialect.class, reason = "Value is too big for the maximum allowed precision of Firebird")
|
||||
public void numericType() {
|
||||
createEntityManagerFactory(
|
||||
NumericEntity.class
|
||||
|
@ -191,6 +194,7 @@ public class NativeQueryResultTypeAutoDiscoveryTest {
|
|||
@SkipForDialect(dialectClass = OracleDialect.class, reason = "Value is too big for the maximum allowed precision of Oracle")
|
||||
@SkipForDialect(dialectClass = AbstractTransactSQLDialect.class, matchSubTypes = true, reason = "Value is too big for the maximum allowed precision of SQL Server and Sybase")
|
||||
@SkipForDialect(dialectClass = AbstractHANADialect.class, matchSubTypes = true, reason = "Value is too big for the maximum allowed precision of HANA")
|
||||
@SkipForDialect(dialectClass = FirebirdDialect.class, reason = "Value is too big for the maximum allowed precision of Firebird")
|
||||
public void decimalType() {
|
||||
createEntityManagerFactory( DecimalEntity.class );
|
||||
doTest( DecimalEntity.class, new BigDecimal( "5464384284258458485484848458.48465843584584684" ) );
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
|||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
|
||||
import org.hibernate.community.dialect.FirebirdDialect;
|
||||
import org.hibernate.dialect.SQLServerDialect;
|
||||
import org.hibernate.dialect.SybaseDialect;
|
||||
import org.hibernate.mapping.Collection;
|
||||
|
@ -25,7 +26,7 @@ import static org.hamcrest.CoreMatchers.is;
|
|||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
@SkipForDialect({SQLServerDialect.class, SybaseDialect.class})
|
||||
@SkipForDialect({SQLServerDialect.class, SybaseDialect.class, FirebirdDialect.class})
|
||||
public class SubselectFetchWithFormulaTest extends BaseNonConfigCoreFunctionalTestCase {
|
||||
@Override
|
||||
protected String getBaseForMappings() {
|
||||
|
|
|
@ -15,6 +15,7 @@ import jakarta.persistence.criteria.Root;
|
|||
import org.hibernate.annotations.DialectOverride;
|
||||
import org.hibernate.annotations.Formula;
|
||||
|
||||
import org.hibernate.community.dialect.FirebirdDialect;
|
||||
import org.hibernate.dialect.DB2Dialect;
|
||||
import org.hibernate.dialect.DerbyDialect;
|
||||
import org.hibernate.dialect.HSQLDialect;
|
||||
|
@ -105,7 +106,7 @@ public class FormulaTests {
|
|||
@Formula(value = "credit * rate")
|
||||
private Double interest;
|
||||
|
||||
@Formula(value = "rate * 100 || '%'")
|
||||
@Formula(value = "(rate * 100) || '%'")
|
||||
@DialectOverride.Formula(dialect = MySQLDialect.class,
|
||||
override = @Formula("concat(rate * 100, '%')"))
|
||||
@DialectOverride.Formula(dialect = HSQLDialect.class,
|
||||
|
@ -120,6 +121,8 @@ public class FormulaTests {
|
|||
override = @Formula("ltrim(str(rate * 100, 10, 2)) + '%'"))
|
||||
@DialectOverride.Formula(dialect = SybaseDialect.class,
|
||||
override = @Formula("ltrim(str(rate * 100, 10, 2)) + '%'"))
|
||||
@DialectOverride.Formula(dialect = FirebirdDialect.class,
|
||||
override = @Formula("cast(rate * 100 as decimal(10,2)) || '%'"))
|
||||
private String ratePercent;
|
||||
|
||||
public Long getId() {
|
||||
|
|
|
@ -14,6 +14,9 @@ import org.hibernate.mapping.Column;
|
|||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.Selectable;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.anyOf;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
|
@ -68,7 +71,7 @@ public class LegacyJpaNamingWithAnnotationBindingTests extends BaseAnnotationBin
|
|||
|
||||
@Override
|
||||
protected void validateOrderPrimaryTableName(String name) {
|
||||
assertEquals( "Order", name );
|
||||
assertThat( name, anyOf( equalTo( "Order"), equalTo( "`Order`") ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -172,7 +175,7 @@ public class LegacyJpaNamingWithAnnotationBindingTests extends BaseAnnotationBin
|
|||
|
||||
@Override
|
||||
protected void validateCustomerOrdersTableName(String name) {
|
||||
assertEquals( "Order", name );
|
||||
assertThat( name, anyOf( equalTo( "Order"), equalTo( "`Order`") ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,6 +16,9 @@ import org.hibernate.mapping.Selectable;
|
|||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.anyOf;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
|
@ -74,7 +77,7 @@ public class LegacyJpaNamingWithHbmBindingTests extends BaseHbmBindingTests {
|
|||
|
||||
@Override
|
||||
protected void validateOrderPrimaryTableName(String name) {
|
||||
assertEquals( "Order", name );
|
||||
assertThat( name, anyOf( equalTo( "Order"), equalTo( "`Order`") ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -174,7 +177,7 @@ public class LegacyJpaNamingWithHbmBindingTests extends BaseHbmBindingTests {
|
|||
|
||||
@Override
|
||||
protected void validateCustomerOrdersTableName(String name) {
|
||||
assertEquals( "Order", name );
|
||||
assertThat( name, anyOf( equalTo( "Order"), equalTo( "`Order`") ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,9 +6,12 @@
|
|||
*/
|
||||
package org.hibernate.orm.test.query;
|
||||
|
||||
import org.hibernate.community.dialect.FirebirdDialect;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.SkipForDialect;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
|
@ -22,6 +25,9 @@ import jakarta.persistence.Table;
|
|||
@DomainModel(
|
||||
annotatedClasses = NativeQueryWithParenthesesTest.Person.class
|
||||
)
|
||||
@SkipForDialect(dialectClass = FirebirdDialect.class, majorVersion = 4, reason = "Firebird 4.0 and earlier don't support simple query grouping")
|
||||
@SkipForDialect(dialectClass = FirebirdDialect.class, majorVersion = 3, reason = "Firebird 4.0 and earlier don't support simple query grouping")
|
||||
@SkipForDialect(dialectClass = FirebirdDialect.class, majorVersion = 2, reason = "Firebird 4.0 and earlier don't support simple query grouping")
|
||||
@SessionFactory
|
||||
public class NativeQueryWithParenthesesTest {
|
||||
|
||||
|
|
|
@ -365,8 +365,8 @@ public class FunctionTests {
|
|||
public void testAsciiChrFunctions(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
assertThat( session.createQuery("select chr(65)").getSingleResult(), is('A') );
|
||||
assertThat( session.createQuery("select ascii('A')").getSingleResult(), is(65) );
|
||||
assertThat( session.createQuery("select chr(65)").getSingleResult(), is( 'A' ) );
|
||||
assertThat( session.createQuery("select ascii('A')").getSingleResult(), anyOf( is( 65 ), is( (short) 65 ) ) );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -1327,6 +1327,7 @@ public class FunctionTests {
|
|||
|
||||
@Test
|
||||
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsTimezoneTypes.class)
|
||||
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsFormat.class, comment = "We extract the offset with a format function")
|
||||
public void testExtractFunctionTimeZone(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
|
|
|
@ -629,6 +629,7 @@ public class StandardFunctionTests {
|
|||
|
||||
@Test
|
||||
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsTimezoneTypes.class)
|
||||
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsFormat.class, comment = "We extract the offset with a format function")
|
||||
public void testExtractFunctionTimeZone(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
|
|
|
@ -15,6 +15,7 @@ import jakarta.persistence.Entity;
|
|||
import jakarta.persistence.Id;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.community.dialect.FirebirdDialect;
|
||||
import org.hibernate.dialect.DB2Dialect;
|
||||
import org.hibernate.dialect.DerbyDialect;
|
||||
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
|
||||
|
@ -27,6 +28,7 @@ import org.junit.Test;
|
|||
*/
|
||||
@SkipForDialect(value = DB2Dialect.class, comment = "DB2 is far more resistant to the reserved keyword usage. See HHH-12832.")
|
||||
@SkipForDialect(value = DerbyDialect.class, comment = "Derby is far more resistant to the reserved keyword usage.")
|
||||
@SkipForDialect(value = FirebirdDialect.class, comment = "FirebirdDialect has autoQuoteKeywords enabled, so it is far more resistant to the reserved keyword usage.")
|
||||
public class SchemaMigratorHaltOnErrorTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.boot.MetadataSources;
|
|||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.community.dialect.FirebirdDialect;
|
||||
import org.hibernate.dialect.DB2Dialect;
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.junit4.CustomRunner;
|
||||
|
@ -39,6 +40,7 @@ import org.junit.runner.RunWith;
|
|||
*/
|
||||
@SkipForDialect(value = DB2Dialect.class, comment = "DB2 is far more resistant to the reserved keyword usage. See HHH-12832.")
|
||||
@SkipForDialect(value = DerbyDialect.class, comment = "Derby is far more resistant to the reserved keyword usage.")
|
||||
@SkipForDialect(value = FirebirdDialect.class, comment = "FirebirdDialect has autoQuoteKeywords enabled, so it is far more resistant to the reserved keyword usage.")
|
||||
@RunWith(CustomRunner.class)
|
||||
public class SchemaUpdateHaltOnErrorTest {
|
||||
|
||||
|
|
|
@ -12,11 +12,14 @@ import java.nio.charset.Charset;
|
|||
import java.nio.file.Files;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.tool.hbm2ddl.SchemaExport;
|
||||
import org.hibernate.tool.schema.TargetType;
|
||||
|
@ -27,7 +30,8 @@ import org.junit.After;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
|
@ -166,13 +170,8 @@ public class ForeignKeyGenerationTest extends BaseUnitTestCase {
|
|||
throws Exception {
|
||||
final String expectedAlterTableStatement = alterTableStatement.toSQL();
|
||||
final List<String> sqlLines = Files.readAllLines( output.toPath(), Charset.defaultCharset() );
|
||||
boolean found = false;
|
||||
for ( String line : sqlLines ) {
|
||||
if ( line.contains( expectedAlterTableStatement ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
assertThat( "Expected alter table statement not found : " + expectedAlterTableStatement, found, is( true ) );
|
||||
|
||||
assertThat( "Expected alter table statement not found", sqlLines, hasItem( containsString( expectedAlterTableStatement ) ) );
|
||||
}
|
||||
|
||||
private static class AlterTableStatement {
|
||||
|
@ -196,7 +195,13 @@ public class ForeignKeyGenerationTest extends BaseUnitTestCase {
|
|||
}
|
||||
|
||||
public String toSQL() {
|
||||
return ssr.getService( JdbcEnvironment.class ).getDialect().getAlterTableString( tableName ) + " add constraint " + fkConstraintName + " foreign key (" + fkColumnName + ") references " + referenceTableName;
|
||||
JdbcEnvironment jdbcEnvironment = ssr.getService( JdbcEnvironment.class );
|
||||
Dialect dialect = jdbcEnvironment.getDialect();
|
||||
IdentifierHelper identifierHelper = jdbcEnvironment.getIdentifierHelper();
|
||||
UnaryOperator<String> asIdentifier = identifier -> identifierHelper.toIdentifier( identifier ).render( dialect );
|
||||
return dialect.getAlterTableString( asIdentifier.apply( tableName ) )
|
||||
+ " add constraint " + asIdentifier.apply( fkConstraintName )
|
||||
+ " foreign key (" + asIdentifier.apply( fkColumnName ) + ") references " + asIdentifier.apply( referenceTableName );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,11 +22,14 @@ import java.nio.charset.Charset;
|
|||
import java.nio.file.Files;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.tool.hbm2ddl.SchemaExport;
|
||||
import org.hibernate.tool.schema.TargetType;
|
||||
|
@ -38,7 +41,8 @@ import org.junit.Test;
|
|||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
|
@ -77,13 +81,8 @@ public class JoinedInheritanceForeignKeyTest extends BaseUnitTestCase {
|
|||
throws Exception {
|
||||
final String expectedAlterTableStatement = alterTableStatement.toSQL();
|
||||
final List<String> sqlLines = Files.readAllLines( output.toPath(), Charset.defaultCharset() );
|
||||
boolean found = false;
|
||||
for ( String line : sqlLines ) {
|
||||
if ( line.contains( expectedAlterTableStatement ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
assertThat( "Expected alter table statement not found : " + expectedAlterTableStatement, found, is( true ) );
|
||||
|
||||
assertThat( "Expected alter table statement not found", sqlLines, hasItem( containsString( expectedAlterTableStatement ) ) );
|
||||
}
|
||||
|
||||
private static class AlterTableStatement {
|
||||
|
@ -106,7 +105,13 @@ public class JoinedInheritanceForeignKeyTest extends BaseUnitTestCase {
|
|||
}
|
||||
|
||||
public String toSQL() {
|
||||
return ssr.getService( JdbcEnvironment.class ).getDialect().getAlterTableString( tableName ) + " add constraint " + fkConstraintName + " foreign key (" + fkColumnName + ") references " + referenceTableName;
|
||||
JdbcEnvironment jdbcEnvironment = ssr.getService( JdbcEnvironment.class );
|
||||
Dialect dialect = jdbcEnvironment.getDialect();
|
||||
IdentifierHelper identifierHelper = jdbcEnvironment.getIdentifierHelper();
|
||||
UnaryOperator<String> asIdentifier = identifier -> identifierHelper.toIdentifier( identifier ).render( dialect );
|
||||
return dialect.getAlterTableString( asIdentifier.apply( tableName ) )
|
||||
+ " add constraint " + asIdentifier.apply( fkConstraintName )
|
||||
+ " foreign key (" + asIdentifier.apply( fkColumnName ) + ") references " + asIdentifier.apply( referenceTableName );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,8 @@ import jakarta.persistence.GenerationType;
|
|||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.SequenceGenerator;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
@BaseUnitTest
|
||||
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsSequences.class)
|
||||
|
@ -56,7 +57,7 @@ public class SequenceGeneratorIncrementTest {
|
|||
createSchema();
|
||||
|
||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
|
||||
assertTrue( fileContent.contains( "increment by 50" ) );
|
||||
assertThat( fileContent, containsString( "increment by 50" ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -66,7 +67,7 @@ public class SequenceGeneratorIncrementTest {
|
|||
createSchema();
|
||||
|
||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
|
||||
assertTrue( fileContent.contains( "increment by 1" ) );
|
||||
assertThat( fileContent, containsString( "increment by 1" ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -76,7 +77,7 @@ public class SequenceGeneratorIncrementTest {
|
|||
createSchema();
|
||||
|
||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
|
||||
assertTrue( fileContent.contains( "increment by 50" ) );
|
||||
assertThat( fileContent, containsString( "increment by 50" ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -86,7 +87,7 @@ public class SequenceGeneratorIncrementTest {
|
|||
createSchema();
|
||||
|
||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
|
||||
assertTrue( fileContent.contains( "increment by 1" ) );
|
||||
assertThat( fileContent, containsString( "increment by 1" ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -96,7 +97,7 @@ public class SequenceGeneratorIncrementTest {
|
|||
createSchema();
|
||||
|
||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
|
||||
assertTrue( fileContent.contains( "increment by 50" ) );
|
||||
assertThat( fileContent, containsString( "increment by 50" ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -106,7 +107,7 @@ public class SequenceGeneratorIncrementTest {
|
|||
createSchema();
|
||||
|
||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
|
||||
assertTrue( fileContent.contains( "increment by 50" ) );
|
||||
assertThat( fileContent, containsString( "increment by 50" ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -116,7 +117,7 @@ public class SequenceGeneratorIncrementTest {
|
|||
createSchema();
|
||||
|
||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
|
||||
assertTrue( fileContent.contains( "increment by 20" ) );
|
||||
assertThat( fileContent, containsString( "increment by 20" ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -126,7 +127,7 @@ public class SequenceGeneratorIncrementTest {
|
|||
createSchema();
|
||||
|
||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
|
||||
assertTrue( fileContent.contains( "increment by 20" ) );
|
||||
assertThat( fileContent, containsString( "increment by 20" ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -136,7 +137,7 @@ public class SequenceGeneratorIncrementTest {
|
|||
createSchema();
|
||||
|
||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
|
||||
assertTrue( fileContent.contains( "increment by 50" ) );
|
||||
assertThat( fileContent, containsString( "increment by 50" ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -146,7 +147,7 @@ public class SequenceGeneratorIncrementTest {
|
|||
createSchema();
|
||||
|
||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
|
||||
assertTrue( fileContent.contains( "increment by 1" ) );
|
||||
assertThat( fileContent, containsString( "increment by 1" ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -156,7 +157,7 @@ public class SequenceGeneratorIncrementTest {
|
|||
createSchema();
|
||||
|
||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
|
||||
assertTrue( fileContent.contains( "increment by 10" ) );
|
||||
assertThat( fileContent, containsString( "increment by 10" ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -166,7 +167,7 @@ public class SequenceGeneratorIncrementTest {
|
|||
createSchema();
|
||||
|
||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
|
||||
assertTrue( fileContent.contains( "increment by 10" ) );
|
||||
assertThat( fileContent, containsString( "increment by 10" ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -176,7 +177,7 @@ public class SequenceGeneratorIncrementTest {
|
|||
createSchema();
|
||||
|
||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
|
||||
assertTrue( fileContent.contains( "increment by 50" ) );
|
||||
assertThat( fileContent, containsString( "increment by 50" ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -189,7 +190,7 @@ public class SequenceGeneratorIncrementTest {
|
|||
createSchema();
|
||||
|
||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) );
|
||||
assertTrue( fileContent.contains( "increment by 1" ) );
|
||||
assertThat( fileContent, containsString( "increment by 1" ) );
|
||||
}
|
||||
|
||||
private void buildMetadata(Class annotatedClass) {
|
||||
|
|
|
@ -78,6 +78,30 @@ public class LazyManyToManyNonUniqueIdWhereTest extends BaseCoreFunctionalTestCa
|
|||
"primary key (ID, CODE) )"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table ASSOCIATION_TABLE( " +
|
||||
"MAIN_ID integer not null, MAIN_CODE varchar(10) not null, " +
|
||||
"ASSOCIATION_ID int not null, ASSOCIATION_CODE varchar(10) not null, " +
|
||||
"primary key (MAIN_ID, MAIN_CODE, ASSOCIATION_ID, ASSOCIATION_CODE))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table MATERIAL_RATINGS( " +
|
||||
"MATERIAL_ID integer not null, RATING_ID integer not null," +
|
||||
" primary key (MATERIAL_ID, RATING_ID))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table BUILDING_RATINGS( " +
|
||||
"BUILDING_ID integer not null, RATING_ID integer not null," +
|
||||
" primary key (BUILDING_ID, RATING_ID))"
|
||||
).executeUpdate();
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
|
||||
session.createNativeQuery( "insert into MAIN_TABLE(ID, NAME, CODE) VALUES( 1, 'plastic', 'MATERIAL' )" )
|
||||
.executeUpdate();
|
||||
session.createNativeQuery( "insert into MAIN_TABLE(ID, NAME, CODE) VALUES( 1, 'house', 'BUILDING' )" )
|
||||
|
@ -93,13 +117,6 @@ public class LazyManyToManyNonUniqueIdWhereTest extends BaseCoreFunctionalTestCa
|
|||
session.createNativeQuery( "insert into MAIN_TABLE(ID, NAME, CODE) VALUES( 2, 'medium', 'SIZE' )" )
|
||||
.executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table ASSOCIATION_TABLE( " +
|
||||
"MAIN_ID integer not null, MAIN_CODE varchar(10) not null, " +
|
||||
"ASSOCIATION_ID int not null, ASSOCIATION_CODE varchar(10) not null, " +
|
||||
"primary key (MAIN_ID, MAIN_CODE, ASSOCIATION_ID, ASSOCIATION_CODE))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"insert into ASSOCIATION_TABLE(MAIN_ID, MAIN_CODE, ASSOCIATION_ID, ASSOCIATION_CODE) " +
|
||||
"VALUES( 1, 'MATERIAL', 1, 'RATING' )"
|
||||
|
@ -128,23 +145,10 @@ public class LazyManyToManyNonUniqueIdWhereTest extends BaseCoreFunctionalTestCa
|
|||
"VALUES( 1, 'BUILDING', 1, 'SIZE' )"
|
||||
).executeUpdate();
|
||||
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table MATERIAL_RATINGS( " +
|
||||
"MATERIAL_ID integer not null, RATING_ID integer not null," +
|
||||
" primary key (MATERIAL_ID, RATING_ID))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"insert into MATERIAL_RATINGS(MATERIAL_ID, RATING_ID) VALUES( 1, 1 )"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table BUILDING_RATINGS( " +
|
||||
"BUILDING_ID integer not null, RATING_ID integer not null," +
|
||||
" primary key (BUILDING_ID, RATING_ID))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"insert into BUILDING_RATINGS(BUILDING_ID, RATING_ID) VALUES( 1, 1 )"
|
||||
).executeUpdate();
|
||||
|
|
|
@ -72,6 +72,11 @@ public class LazyOneToManyNonUniqueIdWhereTest extends BaseCoreFunctionalTestCas
|
|||
"MATERIAL_OWNER_ID integer, BUILDING_OWNER_ID integer, " +
|
||||
"primary key (ID, CODE) )"
|
||||
).executeUpdate();
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
|
||||
session.createNativeQuery( "insert into MAIN_TABLE(ID, NAME, CODE) VALUES( 1, 'plastic', 'MATERIAL' )" )
|
||||
.executeUpdate();
|
||||
|
|
|
@ -57,6 +57,29 @@ public class LazyManyToManyNonUniqueIdNotFoundWhereTest extends BaseCoreFunction
|
|||
"primary key (ID, CODE) )"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table ASSOCIATION_TABLE( " +
|
||||
"MAIN_ID integer not null, MAIN_CODE varchar(10) not null, " +
|
||||
"ASSOCIATION_ID int not null, ASSOCIATION_CODE varchar(10) not null, " +
|
||||
"primary key (MAIN_ID, MAIN_CODE, ASSOCIATION_ID, ASSOCIATION_CODE))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table BUILDING_RATINGS( " +
|
||||
"BUILDING_ID integer not null, RATING_ID integer not null," +
|
||||
" primary key (BUILDING_ID, RATING_ID))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table MATERIAL_RATINGS( " +
|
||||
"MATERIAL_ID integer not null, RATING_ID integer not null," +
|
||||
" primary key (MATERIAL_ID, RATING_ID))"
|
||||
).executeUpdate();
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
session.createNativeQuery( "insert into MAIN_TABLE(ID, NAME, CODE) VALUES( 1, 'plastic', 'MATERIAL' )" )
|
||||
.executeUpdate();
|
||||
session.createNativeQuery( "insert into MAIN_TABLE(ID, NAME, CODE) VALUES( 1, 'house', 'BUILDING' )" )
|
||||
|
@ -66,13 +89,6 @@ public class LazyManyToManyNonUniqueIdNotFoundWhereTest extends BaseCoreFunction
|
|||
session.createNativeQuery( "insert into MAIN_TABLE(ID, NAME, CODE) VALUES( 1, 'small', 'SIZE' )" )
|
||||
.executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table ASSOCIATION_TABLE( " +
|
||||
"MAIN_ID integer not null, MAIN_CODE varchar(10) not null, " +
|
||||
"ASSOCIATION_ID int not null, ASSOCIATION_CODE varchar(10) not null, " +
|
||||
"primary key (MAIN_ID, MAIN_CODE, ASSOCIATION_ID, ASSOCIATION_CODE))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"insert into ASSOCIATION_TABLE(MAIN_ID, MAIN_CODE, ASSOCIATION_ID, ASSOCIATION_CODE) " +
|
||||
"VALUES( 1, 'MATERIAL', 1, 'RATING' )"
|
||||
|
@ -118,12 +134,6 @@ public class LazyManyToManyNonUniqueIdNotFoundWhereTest extends BaseCoreFunction
|
|||
"VALUES( 1, 'BUILDING', 2, 'SIZE' )"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table MATERIAL_RATINGS( " +
|
||||
"MATERIAL_ID integer not null, RATING_ID integer not null," +
|
||||
" primary key (MATERIAL_ID, RATING_ID))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"insert into MATERIAL_RATINGS(MATERIAL_ID, RATING_ID) VALUES( 1, 1 )"
|
||||
).executeUpdate();
|
||||
|
@ -133,13 +143,6 @@ public class LazyManyToManyNonUniqueIdNotFoundWhereTest extends BaseCoreFunction
|
|||
"insert into MATERIAL_RATINGS(MATERIAL_ID, RATING_ID) VALUES( 1, 2 )"
|
||||
).executeUpdate();
|
||||
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table BUILDING_RATINGS( " +
|
||||
"BUILDING_ID integer not null, RATING_ID integer not null," +
|
||||
" primary key (BUILDING_ID, RATING_ID))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"insert into BUILDING_RATINGS(BUILDING_ID, RATING_ID) VALUES( 1, 1 )"
|
||||
).executeUpdate();
|
||||
|
|
|
@ -63,6 +63,30 @@ public class LazyManyToManyNonUniqueIdWhereTest extends BaseCoreFunctionalTestCa
|
|||
"primary key (ID, CODE) )"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table ASSOCIATION_TABLE( " +
|
||||
"MAIN_ID integer not null, MAIN_CODE varchar(10) not null, " +
|
||||
"ASSOCIATION_ID int not null, ASSOCIATION_CODE varchar(10) not null, " +
|
||||
"primary key (MAIN_ID, MAIN_CODE, ASSOCIATION_ID, ASSOCIATION_CODE))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table MATERIAL_RATINGS( " +
|
||||
"MATERIAL_ID integer not null, RATING_ID integer not null," +
|
||||
" primary key (MATERIAL_ID, RATING_ID))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table BUILDING_RATINGS( " +
|
||||
"BUILDING_ID integer not null, RATING_ID integer not null," +
|
||||
" primary key (BUILDING_ID, RATING_ID))"
|
||||
).executeUpdate();
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
|
||||
session.createNativeQuery( "insert into MAIN_TABLE(ID, NAME, CODE) VALUES( 1, 'plastic', 'MATERIAL' )" )
|
||||
.executeUpdate();
|
||||
session.createNativeQuery( "insert into MAIN_TABLE(ID, NAME, CODE) VALUES( 1, 'house', 'BUILDING' )" )
|
||||
|
@ -78,13 +102,6 @@ public class LazyManyToManyNonUniqueIdWhereTest extends BaseCoreFunctionalTestCa
|
|||
session.createNativeQuery( "insert into MAIN_TABLE(ID, NAME, CODE) VALUES( 2, 'medium', 'SIZE' )" )
|
||||
.executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table ASSOCIATION_TABLE( " +
|
||||
"MAIN_ID integer not null, MAIN_CODE varchar(10) not null, " +
|
||||
"ASSOCIATION_ID int not null, ASSOCIATION_CODE varchar(10) not null, " +
|
||||
"primary key (MAIN_ID, MAIN_CODE, ASSOCIATION_ID, ASSOCIATION_CODE))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"insert into ASSOCIATION_TABLE(MAIN_ID, MAIN_CODE, ASSOCIATION_ID, ASSOCIATION_CODE) " +
|
||||
"VALUES( 1, 'MATERIAL', 1, 'RATING' )"
|
||||
|
@ -113,23 +130,10 @@ public class LazyManyToManyNonUniqueIdWhereTest extends BaseCoreFunctionalTestCa
|
|||
"VALUES( 1, 'BUILDING', 1, 'SIZE' )"
|
||||
).executeUpdate();
|
||||
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table MATERIAL_RATINGS( " +
|
||||
"MATERIAL_ID integer not null, RATING_ID integer not null," +
|
||||
" primary key (MATERIAL_ID, RATING_ID))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"insert into MATERIAL_RATINGS(MATERIAL_ID, RATING_ID) VALUES( 1, 1 )"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"create table BUILDING_RATINGS( " +
|
||||
"BUILDING_ID integer not null, RATING_ID integer not null," +
|
||||
" primary key (BUILDING_ID, RATING_ID))"
|
||||
).executeUpdate();
|
||||
|
||||
session.createNativeQuery(
|
||||
"insert into BUILDING_RATINGS(BUILDING_ID, RATING_ID) VALUES( 1, 1 )"
|
||||
).executeUpdate();
|
||||
|
|
|
@ -59,7 +59,11 @@ public class LazyOneToManyNonUniqueIdWhereTest extends BaseCoreFunctionalTestCas
|
|||
"MATERIAL_OWNER_ID integer, BUILDING_OWNER_ID integer, " +
|
||||
"primary key (ID, CODE) )"
|
||||
).executeUpdate();
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate(
|
||||
this::sessionFactory, session -> {
|
||||
session.createNativeQuery( "insert into MAIN_TABLE(ID, NAME, CODE) VALUES( 1, 'plastic', 'MATERIAL' )" )
|
||||
.executeUpdate();
|
||||
session.createNativeQuery( "insert into MAIN_TABLE(ID, NAME, CODE) VALUES( 1, 'house', 'BUILDING' )" )
|
||||
|
|
|
@ -11,6 +11,7 @@ apply from: rootProject.file( 'gradle/published-java-module.gradle' )
|
|||
|
||||
dependencies {
|
||||
api project( ':hibernate-core' )
|
||||
api project( ':hibernate-community-dialects' )
|
||||
|
||||
api testLibs.junit4
|
||||
api testLibs.junit5Api
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.testing;
|
||||
|
||||
import org.hibernate.community.dialect.FirebirdDialect;
|
||||
import org.hibernate.dialect.AbstractHANADialect;
|
||||
import org.hibernate.dialect.CockroachDialect;
|
||||
import org.hibernate.dialect.DB2Dialect;
|
||||
|
@ -229,7 +230,9 @@ abstract public class DialectChecks {
|
|||
|
||||
public static class SupportsJdbcDriverProxying implements DialectCheck {
|
||||
public boolean isMatch(Dialect dialect) {
|
||||
return !( dialect instanceof DB2Dialect ) && !( dialect instanceof DerbyDialect );
|
||||
return !( dialect instanceof DB2Dialect
|
||||
|| dialect instanceof DerbyDialect
|
||||
|| dialect instanceof FirebirdDialect );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.testing.orm.junit;
|
||||
|
||||
import org.hibernate.community.dialect.FirebirdDialect;
|
||||
import org.hibernate.dialect.AbstractHANADialect;
|
||||
import org.hibernate.dialect.CockroachDialect;
|
||||
import org.hibernate.dialect.DB2Dialect;
|
||||
|
@ -152,7 +153,9 @@ abstract public class DialectFeatureChecks {
|
|||
|
||||
public static class SupportsJdbcDriverProxying implements DialectFeatureCheck {
|
||||
public boolean apply(Dialect dialect) {
|
||||
return !( dialect instanceof DB2Dialect ) && !( dialect instanceof DerbyDialect );
|
||||
return !( dialect instanceof DB2Dialect
|
||||
|| dialect instanceof DerbyDialect
|
||||
|| dialect instanceof FirebirdDialect );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -452,6 +455,7 @@ abstract public class DialectFeatureChecks {
|
|||
return !( dialect instanceof MySQLDialect
|
||||
|| dialect instanceof SybaseDialect
|
||||
|| dialect instanceof DerbyDialect
|
||||
|| dialect instanceof FirebirdDialect
|
||||
|| dialect instanceof DB2Dialect && ( (DB2Dialect) dialect ).getDB2Version().isBefore( 11 ) )
|
||||
|| dialect instanceof MariaDBDialect;
|
||||
}
|
||||
|
|
|
@ -202,7 +202,7 @@ dependencyResolutionManagement {
|
|||
alias( "hana" ).to( "com.sap.cloud.db.jdbc", "ngdbc" ).version( "2.4.59" )
|
||||
alias( "sybase" ).to( "net.sourceforge.jtds", "jtds" ).version( "1.3.1" )
|
||||
alias( "informix" ).to( "com.ibm.informix", "jdbc" ).version( "4.10.12" )
|
||||
alias( "firebird" ).to( "org.firebirdsql.jdbc", "jaybird" ).version( "4.0.3.java8" )
|
||||
alias( "firebird" ).to( "org.firebirdsql.jdbc", "jaybird" ).version( "4.0.8.java11" )
|
||||
}
|
||||
mavenLibs {
|
||||
alias( "mavenCore" ).to( "org.apache.maven", "maven-core" ).version( "3.8.1" )
|
||||
|
|
Loading…
Reference in New Issue