HHH-17355 Add array_agg documentation and add it to NodeBuilder

This commit is contained in:
Christian Beikov 2023-10-27 12:10:47 +02:00
parent eeca5300fa
commit f2e6ad6741
4 changed files with 80 additions and 0 deletions

View File

@ -1118,6 +1118,7 @@ The following functions deal with SQL array types, which are not supported on ev
| Function | Purpose
| `array()` | Creates an array based on the passed arguments
| `array_agg()` | Aggregates row values into an array
| `array_position()` | Determines the position of an element in an array
| `array_length()` | Determines the length of an array
| `array_concat()` | Concatenates array with each other in order
@ -1147,6 +1148,18 @@ include::{array-example-dir-hql}/ArrayConstructorTest.java[tags=hql-array-exampl
----
====
===== `array_agg()`
An <<hql-aggregate-functions-orderedset,ordered set aggregate function>> that aggregates values to an array.
[[hql-array-agg-example]]
====
[source, JAVA, indent=0]
----
include::{array-example-dir-hql}/ArrayAggregateTest.java[tags=hql-array-agg-example]
----
====
[[hql-array-position-functions]]
===== `array_position()`

View File

@ -17,6 +17,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hibernate.Incubating;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.query.NullPrecedence;
@ -25,10 +26,13 @@ import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.query.criteria.JpaCoalesce;
import org.hibernate.query.criteria.JpaCompoundSelection;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaOrder;
import org.hibernate.query.criteria.JpaParameterExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.criteria.JpaSearchedCase;
import org.hibernate.query.criteria.JpaSelection;
import org.hibernate.query.criteria.JpaSimpleCase;
import org.hibernate.query.criteria.JpaWindow;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement;
import org.hibernate.query.sqm.tree.domain.SqmBagJoin;
@ -100,6 +104,43 @@ public interface NodeBuilder extends HibernateCriteriaBuilder {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Array functions for array types
/**
* @see #arrayAgg(JpaOrder, JpaPredicate, JpaWindow, Expression)
* @since 6.4
*/
<T> JpaExpression<T[]> arrayAgg(JpaOrder order, Expression<? extends T> argument);
/**
* @see #arrayAgg(JpaOrder, JpaPredicate, JpaWindow, Expression)
* @since 6.4
*/
<T> JpaExpression<T[]> arrayAgg(JpaOrder order, JpaPredicate filter, Expression<? extends T> argument);
/**
* @see #arrayAgg(JpaOrder, JpaPredicate, JpaWindow, Expression)
* @since 6.4
*/
<T> JpaExpression<T[]> arrayAgg(JpaOrder order, JpaWindow window, Expression<? extends T> argument);
/**
* Create a {@code array_agg} ordered set-aggregate function expression.
*
* @param order order by clause used in within group
* @param filter optional filter clause
* @param window optional window over which to apply the function
* @param argument values to aggregate
*
* @return ordered set-aggregate expression
*
* @see #functionWithinGroup(String, Class, JpaOrder, JpaPredicate, JpaWindow, Expression...)
* @since 6.4
*/
<T> JpaExpression<T[]> arrayAgg(
JpaOrder order,
JpaPredicate filter,
JpaWindow window,
Expression<? extends T> argument);
/**
* Creates an array literal with the {@code array} constructor function.
*

View File

@ -3632,6 +3632,30 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
return functionWithinGroup( "percent_rank", Double.class, order, filter, window, arguments );
}
@Override
public <T> JpaExpression<T[]> arrayAgg(JpaOrder order, Expression<? extends T> argument) {
return arrayAgg( order, null, null, argument );
}
@Override
public <T> JpaExpression<T[]> arrayAgg(JpaOrder order, JpaPredicate filter, Expression<? extends T> argument) {
return arrayAgg( order, filter, null, argument );
}
@Override
public <T> JpaExpression<T[]> arrayAgg(JpaOrder order, JpaWindow window, Expression<? extends T> argument) {
return arrayAgg( order, null, window, argument );
}
@Override
public <T> JpaExpression<T[]> arrayAgg(
JpaOrder order,
JpaPredicate filter,
JpaWindow window,
Expression<? extends T> argument) {
return functionWithinGroup( "array_agg", null, order, filter, window, argument );
}
@Override
public <T> SqmExpression<T[]> arrayLiteral(T... elements) {
return getFunctionDescriptor( "array" ).generateSqmExpression(

View File

@ -109,8 +109,10 @@ public class ArrayAggregateTest {
@Test
public void testEmpty(SessionFactoryScope scope) {
scope.inSession( em -> {
//tag::hql-array-agg-example[]
List<String[]> results = em.createQuery( "select array_agg(e.data) within group (order by e.id) from BasicEntity e", String[].class )
.getResultList();
//end::hql-array-agg-example[]
assertEquals( 1, results.size() );
assertNull( results.get( 0 ) );
} );