Skip to content

HHH-19694 Enhanced support for older Informix #10706

New issue

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

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

Already on GitHub? Sign in to your account

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
@Override
public String extractPattern(TemporalUnit unit) {
return switch ( unit ) {
case SECOND -> "to_number(to_char(?2,'%S.%F3'))";
case SECOND -> getVersion().isBefore( 11, 70 ) ? "to_number(to_char(?2,'%S%F3'))" : "to_number(to_char(?2,'%S.%F3'))";
case MINUTE -> "to_number(to_char(?2,'%M'))";
case HOUR -> "to_number(to_char(?2,'%H'))";
case DAY_OF_WEEK -> "(weekday(?2)+1)";
Expand Down Expand Up @@ -536,8 +536,8 @@ public String getAddPrimaryKeyConstraintString(String constraintName) {

@Override
public String getTruncateTableStatement(String tableName) {
return super.getTruncateTableStatement( tableName )
+ " reuse storage keep statistics";
return super.getTruncateTableStatement( tableName ) + " reuse storage"
+ ( getVersion().isSameOrAfter( 12, 10 ) ? " keep statistics" : "" );
}

@Override
Expand Down Expand Up @@ -751,7 +751,7 @@ public boolean isCurrentTimestampSelectStringCallable() {

@Override
public String getCurrentTimestampSelectString() {
return "select sysdate";
return "select sysdate" + (getVersion().isBefore( 12, 10 ) ? " from informix.systables where tabid=1" : "");
}

@Override @SuppressWarnings("deprecation")
Expand Down Expand Up @@ -1111,11 +1111,26 @@ public String getDual() {
return "(select 0 from systables where tabid=1)";
}

@Override
public String getFromDualForSelectOnly() {
return getVersion().isBefore( 12,10 ) ? " from " + getDual() + " dual" : "";
}

@Override
public boolean supportsCrossJoin() {
return false;
}

@Override
public boolean supportsIntersect(){
return getVersion().isSameOrAfter( 12,10 );
}

public boolean supportsSubqueryOnMutatingTable() {
//tested on version 11.50, 14.10
return getVersion().isAfter( 11, 50);
}

@Override
public boolean supportsRowValueConstructorSyntax() {
return false;
Expand All @@ -1131,6 +1146,11 @@ public boolean supportsRowValueConstructorSyntaxInInList() {
return false;
}

@Override
public boolean supportsWithClause() {
return getVersion().isSameOrAfter( 14,10 );
}

@Override
public boolean requiresColumnListInCreateView() {
return true;
Expand All @@ -1147,6 +1167,6 @@ public IdentifierHelper buildIdentifierHelper(IdentifierHelperBuilder builder, @

@Override
public DmlTargetColumnQualifierSupport getDmlTargetColumnQualifierSupport() {
return DmlTargetColumnQualifierSupport.TABLE_ALIAS;
return getVersion().isSameOrAfter( 12,10 ) ? DmlTargetColumnQualifierSupport.TABLE_ALIAS : DmlTargetColumnQualifierSupport.NONE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ protected void visitQueryClauses(QuerySpec querySpec) {
visitSelectClause( querySpec.getSelectClause() );
visitFromClause( querySpec.getFromClause() );
if ( !hasFrom( querySpec.getFromClause() )
&& hasWhere( querySpec.getWhereClauseRestrictions() ) ) {
&& hasWhere( querySpec.getWhereClauseRestrictions() )
&& getDialect().getFromDualForSelectOnly().isBlank() ) {
append( " from " );
append( getDual() );
}
Expand Down Expand Up @@ -321,8 +322,10 @@ public void visitBinaryArithmeticExpression(BinaryArithmeticExpression arithmeti
@Override
protected void renderDmlTargetTableExpression(NamedTableReference tableReference) {
super.renderDmlTargetTableExpression( tableReference );
if ( getClauseStack().getCurrent() != Clause.INSERT ) {
renderTableReferenceIdentificationVariable( tableReference );
if (getDialect().getVersion().isSameOrAfter( 12, 10 )) {
if ( getClauseStack().getCurrent() != Clause.INSERT ) {
renderTableReferenceIdentificationVariable( tableReference );
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,7 @@ public void testFilterApplicationOnHqlQueryWithImplicitSubqueryContainingNamedPa
}

@Test
@RequiresDialectFeature(DialectChecks.SupportsDmlTargetColumnQualifier.class)
public void testFiltersOnSimpleHqlDelete() {
Salesperson sp = new Salesperson();
Salesperson sp2 = new Salesperson();
Expand All @@ -708,6 +709,7 @@ public void testFiltersOnSimpleHqlDelete() {
}

@Test
@RequiresDialectFeature(DialectChecks.SupportsDmlTargetColumnQualifier.class)
public void testFiltersOnMultiTableHqlDelete() {
Salesperson sp = new Salesperson();
Salesperson sp2 = new Salesperson();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ public void testUpdateWithSubquery() {
s.beginTransaction();

// just checking parsing and syntax...
s.createQuery( "update Human h set h.bodyWeight = h.bodyWeight + (select count(1) from IntegerVersioned)" )
s.createQuery( "update Human h set h.bodyWeight = h.bodyWeight + (select count(*) from IntegerVersioned)" )
.executeUpdate();
s.createQuery(
"update Human h set h.bodyWeight = h.bodyWeight + (select count(1) from IntegerVersioned) where h.description = 'abc'" )
"update Human h set h.bodyWeight = h.bodyWeight + (select count(*) from IntegerVersioned) where h.description = 'abc'" )
.executeUpdate();

s.getTransaction().commit();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,7 @@ public void test_hql_aggregate_functions_example_3() {
}

@Test
@SkipForDialect( dialectClass = InformixDialect.class, majorVersion = 11, minorVersion = 50, reason = "Informix does not support case expressions within count function")
public void test_hql_aggregate_functions_simple_filter_example() {
doInJPA(this::entityManagerFactory, entityManager -> {
//tag::hql-aggregate-functions-simple-filter-example[]
Expand All @@ -1502,6 +1503,7 @@ public void test_hql_aggregate_functions_simple_filter_example() {
}

@Test
@SkipForDialect( dialectClass = InformixDialect.class, majorVersion = 11, minorVersion = 50, reason = "Informix does not support case expressions within count function")
public void test_hql_aggregate_functions_filter_example() {
doInJPA(this::entityManagerFactory, entityManager -> {
//tag::hql-aggregate-functions-filter-example[]
Expand Down Expand Up @@ -1647,6 +1649,7 @@ public void test_hql_length_function_example() {
}

@Test
@SkipForDialect( dialectClass = InformixDialect.class, majorVersion = 11, minorVersion = 70, reason = "Informix does not support locate function")
public void test_hql_locate_function_example() {
doInJPA(this::entityManagerFactory, entityManager -> {
//tag::hql-locate-function-example[]
Expand All @@ -1661,6 +1664,7 @@ public void test_hql_locate_function_example() {
}

@Test
@SkipForDialect( dialectClass = InformixDialect.class, majorVersion = 11, minorVersion = 70, reason = "Informix does not support position function")
public void test_hql_position_function_example() {
doInJPA(this::entityManagerFactory, entityManager -> {
//tag::hql-position-function-example[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ public void testBatchingAmongstSubClasses() {

sessionFactoryScope().inTransaction( (session) -> {
final Long specialPersonCount = session
.createSelectionQuery( "select count(1) from SpecialPerson", Long.class )
.createSelectionQuery( "select count(*) from SpecialPerson", Long.class )
.getSingleResult();
assertThat( specialPersonCount ).isEqualTo( 12L );

final Long addressCount = session
.createSelectionQuery( "select count(1) from Address", Long.class )
.createSelectionQuery( "select count(*) from Address", Long.class )
.getSingleResult();
assertThat( addressCount ).isEqualTo( 24L );
} );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,22 +91,22 @@ public void testBatchingAmongstSubClasses() {
// 1 AnotherPerson per loop (2)
// 1 President per loop (2)
final Long addressCount = session
.createSelectionQuery( "select count(1) from Address", Long.class )
.createSelectionQuery( "select count(*) from Address", Long.class )
.getSingleResult();
assertThat( addressCount ).isEqualTo( 4L );

final Long officeCount = session
.createSelectionQuery( "select count(1) from Office", Long.class )
.createSelectionQuery( "select count(*) from Office", Long.class )
.getSingleResult();
assertThat( officeCount ).isEqualTo( 2L );

final Long presidentCount = session
.createSelectionQuery( "select count(1) from President", Long.class )
.createSelectionQuery( "select count(*) from President", Long.class )
.getSingleResult();
assertThat( presidentCount ).isEqualTo( 2L );

final Long anotherPersonCount = session
.createSelectionQuery( "select count(1) from AnotherPerson", Long.class )
.createSelectionQuery( "select count(*) from AnotherPerson", Long.class )
.getSingleResult();
assertThat( presidentCount ).isEqualTo( 2L );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ public void testNegatedCriteriaUsage(SessionFactoryScope scope) {
private int countByCriteria(String attributeName, boolean matchValue, SessionImplementor session) {
final HibernateCriteriaBuilder builder = session.getCriteriaBuilder();
final JpaCriteriaQuery<Long> criteria = builder.createQuery( Long.class );
criteria.select( builder.count( builder.literal( 1 ) ) );
criteria.select( builder.count() );
final JpaRoot<EntityOfBooleans> root = criteria.from( EntityOfBooleans.class );
final JpaPath<Boolean> convertedYesNo = root.get( attributeName );
if ( matchValue ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private void dropTestData(SessionFactoryScope scope) {
session.createQuery( "from Author", Author.class ).list().forEach( session::remove );
} );
scope.inTransaction( (session) -> {
final Long bookCount = session.createSelectionQuery( "select count(1) from Book", Long.class ).uniqueResult();
final Long bookCount = session.createSelectionQuery( "select count(*) from Book", Long.class ).uniqueResult();
assertThat( bookCount ).isEqualTo( 0L );
} );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ private void dropTestData(SessionFactoryScope scope) {
session.createQuery( "from Author", Author.class ).list().forEach( session::remove );
} );
scope.inTransaction( (session) -> {
final Long bookCount = session.createSelectionQuery( "select count(1) from Book", Long.class ).uniqueResult();
final Long bookCount = session.createSelectionQuery( "select count(*) from Book", Long.class ).uniqueResult();
assertThat( bookCount ).isEqualTo( 0L );
} );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.AbstractTransactSQLDialect;
import org.hibernate.dialect.DmlTargetColumnQualifierSupport;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.SybaseDialect;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
Expand Down Expand Up @@ -78,6 +79,9 @@ else if ( DialectContext.getDialect() instanceof SybaseDialect ) {
else if ( DialectContext.getDialect() instanceof AbstractTransactSQLDialect ) {
baseQuery = "update ae1_0 set name=? from AnEntity ae1_0";
}
else if ( DialectContext.getDialect().getDmlTargetColumnQualifierSupport() == DmlTargetColumnQualifierSupport.NONE ) {
baseQuery = "update AnEntity set name=?";
}
else {
baseQuery = "update AnEntity ae1_0 set name=?";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void testGroupByAliasedBasicPart(SessionFactoryScope scope) {
sqlStatementInspector.clear();

scope.inSession( (session) -> {
final String qryString = "select c.id as id_alias, count(1) as occurrences"
final String qryString = "select c.id as id_alias, count(*) as occurrences"
+ " from Contact c"
+ " group by id_alias"
+ " order by id_alias";
Expand All @@ -69,7 +69,7 @@ public void testGroupByAliasedCompositePart(SessionFactoryScope scope) {
sqlStatementInspector.clear();

scope.inTransaction( (session) -> {
final String qryString = "select c.name as name_alias, count(1) as occurrences"
final String qryString = "select c.name as name_alias, count(*) as occurrences"
+ " from Contact c"
+ " group by name_alias"
+ " order by name_alias";
Expand All @@ -94,7 +94,7 @@ public void testGroupByMultipleAliases(SessionFactoryScope scope) {
sqlStatementInspector.clear();

scope.inTransaction( (session) -> {
final String qryString = "select c.id as id_alias, c.gender as gender_alias, count(1) as occurrences"
final String qryString = "select c.id as id_alias, c.gender as gender_alias, count(*) as occurrences"
+ " from Contact c"
+ " group by id_alias, gender_alias"
+ " order by id_alias, gender_alias";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,15 @@ public void testSimpleCountFunctions(SessionFactoryScope scope) {
session -> {
session.createQuery("select count(*) from EntityOfBasics e")
.list();
}
);
}

@Test
@SkipForDialect( dialectClass = InformixDialect.class, majorVersion = 11, minorVersion = 50, reason = "Informix does not support count(1) function")
public void testSimpleCount1Functions(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
session.createQuery("select count(1) from EntityOfBasics e")
.list();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
import org.hibernate.query.MutationQuery;

import org.hibernate.testing.jdbc.SQLStatementInspector;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.Jira;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -47,6 +49,7 @@
MutationQueriesFilterTest.RoleEntity.class
} )
@Jira( "https://hibernate.atlassian.net/browse/HHH-16392" )
@RequiresDialectFeature( feature = DialectFeatureChecks.SupportsDmlTargetColumnQualifier.class )
public class MutationQueriesFilterTest {
@Test
public void testDelete(SessionFactoryScope scope) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
import org.hibernate.query.MutationQuery;

import org.hibernate.testing.jdbc.SQLStatementInspector;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.Jira;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -48,6 +50,7 @@
MutationQueriesWhereAndFilterTest.RoleEntity.class
} )
@Jira( "https://hibernate.atlassian.net/browse/HHH-16392" )
@RequiresDialectFeature( feature = DialectFeatureChecks.SupportsDmlTargetColumnQualifier.class )
public class MutationQueriesWhereAndFilterTest {
@Test
public void testDelete(SessionFactoryScope scope) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
import org.hibernate.query.MutationQuery;

import org.hibernate.testing.jdbc.SQLStatementInspector;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.Jira;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -46,6 +48,7 @@
MutationQueriesWhereTest.RoleEntity.class
} )
@Jira( "https://hibernate.atlassian.net/browse/HHH-16392" )
@RequiresDialectFeature( feature = DialectFeatureChecks.SupportsDmlTargetColumnQualifier.class )
public class MutationQueriesWhereTest {
@Test
public void testDelete(SessionFactoryScope scope) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ private static void verifySecondaryRows(String table, int expectedCount, Session
}

private static void verifySecondaryRows(String table, int expectedCount, SessionImplementor session) {
final String sql = "select count(1) from " + table;
final String sql = "select count(*) from " + table;
final int count = (int) session.createNativeQuery( sql, Integer.class ).getSingleResult();
assertThat( count ).isEqualTo( expectedCount );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
// make sure all 3 are still physically there
session.doWork( (connection) -> {
final Statement statement = connection.createStatement();
final ResultSet resultSet = statement.executeQuery( "select count(1) from implicit_entities" );
final ResultSet resultSet = statement.executeQuery( "select count(*) from implicit_entities" );

Check warning

Code scanning / CodeQL

Potential database resource leak Warning test

This ResultSet is not always closed on method exit.
resultSet.next();
final int count = resultSet.getInt( 1 );
assertThat( count ).isEqualTo( 3 );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public void testNativeQuery(SessionFactoryScope scope) {

statementInspector.clear();
scope.inTransaction( (session) -> {
session.createNativeQuery( "select count(1) from filtered_entity e where e.region = :region" )
session.createNativeQuery( "select count(*) from filtered_entity e where e.region = :region" )
.setParameter( "region", "ABC" )
.uniqueResult();

Expand All @@ -143,7 +143,7 @@ public void testNativeQuery(SessionFactoryScope scope) {

statementInspector.clear();
scope.inTransaction( (session) -> {
session.createNativeQuery( "select count(1) from filtered_entity e where e.region in (:region)" )
session.createNativeQuery( "select count(*) from filtered_entity e where e.region in (:region)" )
.setParameterList( "region", List.of( "ABC", "DEF" ) )
.uniqueResult();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void testUpsertInsert(SessionFactoryScope scope) {


private static void verifySecondaryRows(String table, int expectedCount, SessionFactoryScope sfScope) {
final String sql = "select count(1) from " + table;
final String sql = "select count(*) from " + table;
sfScope.inTransaction( (session) -> {
final int count = (int) session.createNativeQuery( sql, Integer.class ).getSingleResult();
assertThat( count ).isEqualTo( expectedCount );
Expand Down
Loading