HHH-15360 Fix listagg rendering on older H2 versions
This commit is contained in:
parent
2b78f99ea8
commit
0864ca58a3
|
@ -315,11 +315,15 @@ public class H2Dialect extends Dialect {
|
||||||
functionFactory.rownum();
|
functionFactory.rownum();
|
||||||
if ( getVersion().isSameOrAfter( 1, 4, 200 ) ) {
|
if ( getVersion().isSameOrAfter( 1, 4, 200 ) ) {
|
||||||
functionFactory.windowFunctions();
|
functionFactory.windowFunctions();
|
||||||
functionFactory.listagg( null );
|
|
||||||
if ( getVersion().isSameOrAfter( 2 ) ) {
|
if ( getVersion().isSameOrAfter( 2 ) ) {
|
||||||
|
functionFactory.listagg( null );
|
||||||
functionFactory.inverseDistributionOrderedSetAggregates();
|
functionFactory.inverseDistributionOrderedSetAggregates();
|
||||||
functionFactory.hypotheticalOrderedSetAggregates();
|
functionFactory.hypotheticalOrderedSetAggregates();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// Use group_concat until 2.x as listagg was buggy
|
||||||
|
functionFactory.listagg_groupConcat();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
functionFactory.listagg_groupConcat();
|
functionFactory.listagg_groupConcat();
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.query.sqm.ComparisonOperator;
|
import org.hibernate.query.sqm.ComparisonOperator;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||||
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
|
@ -198,6 +199,12 @@ public class H2SqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstT
|
||||||
return getDialect().getVersion().isSameOrAfter( 1, 4, 197 );
|
return getDialect().getVersion().isSameOrAfter( 1, 4, 197 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean supportsNullPrecedence() {
|
||||||
|
// Support for nulls clause in listagg was added in 2.0
|
||||||
|
return getClauseStack().getCurrent() != Clause.WITHIN_GROUP || getDialect().getVersion().isSameOrAfter( 2 );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getFromDual() {
|
protected String getFromDual() {
|
||||||
return " from dual";
|
return " from dual";
|
||||||
|
|
|
@ -590,7 +590,7 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsNullPrecedence() {
|
public boolean supportsNullPrecedence() {
|
||||||
return getVersion().isBefore( 10 );
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -2230,7 +2230,8 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
}
|
}
|
||||||
final boolean renderNullPrecedence = nullPrecedence != null &&
|
final boolean renderNullPrecedence = nullPrecedence != null &&
|
||||||
!nullPrecedence.isDefaultOrdering( sortOrder, getDialect().getNullOrdering() );
|
!nullPrecedence.isDefaultOrdering( sortOrder, getDialect().getNullOrdering() );
|
||||||
if ( renderNullPrecedence && !getDialect().supportsNullPrecedence() ) {
|
final boolean supportsNullPrecedence = renderNullPrecedence && supportsNullPrecedence();
|
||||||
|
if ( renderNullPrecedence && !supportsNullPrecedence ) {
|
||||||
emulateSortSpecificationNullPrecedence( sortExpression, nullPrecedence );
|
emulateSortSpecificationNullPrecedence( sortExpression, nullPrecedence );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2248,12 +2249,16 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
appendSql( " desc" );
|
appendSql( " desc" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( renderNullPrecedence && getDialect().supportsNullPrecedence() ) {
|
if ( renderNullPrecedence && supportsNullPrecedence ) {
|
||||||
appendSql( " nulls " );
|
appendSql( " nulls " );
|
||||||
appendSql( nullPrecedence == NullPrecedence.LAST ? "last" : "first" );
|
appendSql( nullPrecedence == NullPrecedence.LAST ? "last" : "first" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean supportsNullPrecedence() {
|
||||||
|
return getDialect().supportsNullPrecedence();
|
||||||
|
}
|
||||||
|
|
||||||
protected void emulateSortSpecificationNullPrecedence(Expression sortExpression, NullPrecedence nullPrecedence) {
|
protected void emulateSortSpecificationNullPrecedence(Expression sortExpression, NullPrecedence nullPrecedence) {
|
||||||
// TODO: generate "virtual" select items and use them here positionally
|
// TODO: generate "virtual" select items and use them here positionally
|
||||||
appendSql( "case when (" );
|
appendSql( "case when (" );
|
||||||
|
|
|
@ -10,6 +10,7 @@ import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.orm.domain.StandardDomainModel;
|
import org.hibernate.testing.orm.domain.StandardDomainModel;
|
||||||
import org.hibernate.testing.orm.domain.gambit.EntityOfBasics;
|
import org.hibernate.testing.orm.domain.gambit.EntityOfBasics;
|
||||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||||
|
@ -136,6 +137,18 @@ public class OrderedSetAggregateTest {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-15360")
|
||||||
|
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsStringAggregation.class)
|
||||||
|
public void testListaggWithNullsClause(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
TypedQuery<String> q = session.createQuery( "select listagg(eob.theString, ',') within group (order by eob.id desc nulls first) from EntityOfBasics eob", String.class );
|
||||||
|
assertEquals( "5,13,7,6,5", q.getSingleResult() );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsInverseDistributionFunctions.class)
|
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsInverseDistributionFunctions.class)
|
||||||
public void testInverseDistribution(SessionFactoryScope scope) {
|
public void testInverseDistribution(SessionFactoryScope scope) {
|
||||||
|
|
Loading…
Reference in New Issue