diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/HibernateCriteriaBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/HibernateCriteriaBuilder.java index 4afa9302a6..7d2e240142 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/HibernateCriteriaBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/HibernateCriteriaBuilder.java @@ -954,6 +954,11 @@ > JpaPredicate between( */ JpaExpression lastValue(Expression argument, JpaWindow window); + /** + * @see #nthValue(Expression, Expression, JpaWindow) nthValue + */ + JpaExpression nthValue(Expression argument, int n, JpaWindow window); + /** * Create a {@code nth_value} window function expression. * @@ -1012,6 +1017,31 @@ > JpaPredicate between( */ JpaExpression cumeDist(JpaWindow window); + /** + * @see #functionWithinGroup(String, Class, JpaOrder, JpaPredicate, JpaWindow, Expression...) + */ + JpaExpression functionWithinGroup(String name, Class type, JpaOrder order, Expression... args); + + /** + * @see #functionWithinGroup(String, Class, JpaOrder, JpaPredicate, JpaWindow, Expression...) + */ + JpaExpression functionWithinGroup( + String name, + Class type, + JpaOrder order, + JpaPredicate filter, + Expression... args); + + /** + * @see #functionWithinGroup(String, Class, JpaOrder, JpaPredicate, JpaWindow, Expression...) + */ + JpaExpression functionWithinGroup( + String name, + Class type, + JpaOrder order, + JpaWindow window, + Expression... args); + /** * Create a generic ordered set-aggregate function expression. * @@ -1019,6 +1049,7 @@ > JpaPredicate between( * @param type type of this 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 args optional arguments to the function * @param type of this expression * @@ -1029,47 +1060,26 @@ JpaExpression functionWithinGroup( Class type, JpaOrder order, JpaPredicate filter, + JpaWindow window, Expression... args); /** - * Create a generic ordered set-aggregate function expression. - * - * @param name name of the ordered set-aggregate function - * @param type type of this expression - * @param order order by clause used in within group - * @param args optional arguments to the function - * @param type of this expression - * - * @return ordered set-aggregate function expression - * - * @see #functionWithinGroup(String, Class, JpaOrder, JpaPredicate, Expression...) functionWithinGroup + * @see #listagg(JpaOrder, JpaPredicate, JpaWindow, Expression, Expression) */ - JpaExpression functionWithinGroup(String name, Class type, JpaOrder order, Expression... args); + JpaExpression listagg(JpaOrder order, Expression argument, String separator); /** - * Create a {@code listagg} ordered set-aggregate function expression. - * - * @param order order by clause used in within group - * @param argument values to join - * @param separator the separator used to join the values - * - * @return ordered set-aggregate expression - * - * @see #listagg(JpaOrder, JpaPredicate, Expression, Expression) listagg + * @see #listagg(JpaOrder, JpaPredicate, JpaWindow, Expression, Expression) */ JpaExpression listagg(JpaOrder order, Expression argument, Expression separator); /** - * Create a {@code listagg} ordered set-aggregate function expression. - * - * @param order order by clause used in within group - * @param filter optional filter clause - * @param argument values to join - * @param separator the separator used to join the values - * - * @return ordered set-aggregate expression - * - * @see #functionWithinGroup + * @see #listagg(JpaOrder, JpaPredicate, JpaWindow, Expression, Expression) + */ + JpaExpression listagg(JpaOrder order, JpaPredicate filter, Expression argument, String separator); + + /** + * @see #listagg(JpaOrder, JpaPredicate, JpaWindow, Expression, Expression) */ JpaExpression listagg( JpaOrder order, @@ -1078,127 +1088,252 @@ JpaExpression listagg( Expression separator); /** - * Create a {@code mode} ordered set-aggregate function expression. + * @see #listagg(JpaOrder, JpaPredicate, JpaWindow, Expression, Expression) + */ + JpaExpression listagg(JpaOrder order, JpaWindow window, Expression argument, String separator); + + /** + * @see #listagg(JpaOrder, JpaPredicate, JpaWindow, Expression, Expression) + */ + JpaExpression listagg( + JpaOrder order, + JpaWindow window, + Expression argument, + Expression separator); + + /** + * @see #listagg(JpaOrder, JpaPredicate, JpaWindow, Expression, Expression) + */ + JpaExpression listagg( + JpaOrder order, + JpaPredicate filter, + JpaWindow window, + Expression argument, + String separator); + + /** + * Create a {@code listagg} ordered set-aggregate function expression. * * @param order order by clause used in within group - * @param argument argument to the function + * @param filter optional filter clause + * @param window optional window over which to apply the function + * @param argument values to join + * @param separator the separator used to join the values * * @return ordered set-aggregate expression * - * @see #mode(JpaOrder, JpaPredicate, Expression) mode + * @see #functionWithinGroup(String, Class, JpaOrder, JpaPredicate, JpaWindow, Expression...) */ - JpaExpression mode(JpaOrder order, Expression argument); + JpaExpression listagg( + JpaOrder order, + JpaPredicate filter, + JpaWindow window, + Expression argument, + Expression separator); + + /** + * @see #mode(JpaPredicate, JpaWindow, Expression, SortOrder, NullPrecedence) + */ + JpaExpression mode(Expression sortExpression, SortOrder sortOrder, NullPrecedence nullPrecedence); + + /** + * @see #mode(JpaPredicate, JpaWindow, Expression, SortOrder, NullPrecedence) + */ + JpaExpression mode( + JpaPredicate filter, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence); + + /** + * @see #mode(JpaPredicate, JpaWindow, Expression, SortOrder, NullPrecedence) + */ + JpaExpression mode( + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence); /** * Create a {@code mode} ordered set-aggregate function expression. * - * @param order order by clause used in within group * @param filter optional filter clause - * @param argument argument to the function - * + * @param window optional window over which to apply the function + * @param sortExpression the sort expression + * @param sortOrder the sort order + * @param nullPrecedence the null precedence * @return ordered set-aggregate expression - * - * @see #functionWithinGroup + * @param type of this expression + * @see #functionWithinGroup(String, Class, JpaOrder, JpaPredicate, JpaWindow, Expression...) */ - JpaExpression mode(JpaOrder order, JpaPredicate filter, Expression argument); + JpaExpression mode( + JpaPredicate filter, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence); + + /** + * @see #percentileCont(Expression, JpaPredicate, JpaWindow, Expression, SortOrder, NullPrecedence) + */ + JpaExpression percentileCont( + Expression argument, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence); + + /** + * @see #percentileCont(Expression, JpaPredicate, JpaWindow, Expression, SortOrder, NullPrecedence) + */ + JpaExpression percentileCont( + Expression argument, + JpaPredicate filter, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence); + + /** + * @see #percentileCont(Expression, JpaPredicate, JpaWindow, Expression, SortOrder, NullPrecedence) + */ + JpaExpression percentileCont( + Expression argument, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence); /** * Create a {@code percentile_cont} ordered set-aggregate function expression. * - * @param order order by clause used in within group * @param argument argument to the function + * @param filter optional filter clause + * @param window optional window over which to apply the function + * @param sortExpression the sort expression + * @param sortOrder the sort order + * @param nullPrecedence the null precedence * * @return ordered set-aggregate expression * - * @see #percentileCont(JpaOrder, JpaPredicate, Expression) percentileCont + * @see #functionWithinGroup(String, Class, JpaOrder, JpaPredicate, JpaWindow, Expression...) */ - JpaExpression percentileCont(JpaOrder order, Expression argument); + JpaExpression percentileCont( + Expression argument, + JpaPredicate filter, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence); /** - * Create a {@code percentile_cont} ordered set-aggregate function expression. - * - * @param order order by clause used in within group - * @param filter optional filter clause - * @param argument argument to the function - * - * @return ordered set-aggregate expression - * - * @see #functionWithinGroup + * @see #percentileDisc(Expression, JpaPredicate, JpaWindow, Expression, SortOrder, NullPrecedence) */ - JpaExpression percentileCont(JpaOrder order, JpaPredicate filter, Expression argument); + JpaExpression percentileDisc( + Expression argument, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence); + + /** + * @see #percentileDisc(Expression, JpaPredicate, JpaWindow, Expression, SortOrder, NullPrecedence) + */ + JpaExpression percentileDisc( + Expression argument, + JpaPredicate filter, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence); + + /** + * @see #percentileDisc(Expression, JpaPredicate, JpaWindow, Expression, SortOrder, NullPrecedence) + */ + JpaExpression percentileDisc( + Expression argument, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence); /** * Create a {@code percentile_disc} ordered set-aggregate function expression. * - * @param order order by clause used in within group * @param argument argument to the function - * - * @return ordered set-aggregate expression - * - * @see #percentileDisc(JpaOrder, JpaPredicate, Expression) percentileDisc - */ - JpaExpression percentileDisc(JpaOrder order, Expression argument); - - /** - * Create a {@code percentile_disc} ordered set-aggregate function expression. - * - * @param order order by clause used in within group * @param filter optional filter clause - * @param argument argument to the function + * @param window optional window over which to apply the function + * @param sortExpression the sort expression + * @param sortOrder the sort order + * @param nullPrecedence the null precedence * * @return ordered set-aggregate expression * - * @see #functionWithinGroup + * @see #functionWithinGroup(String, Class, JpaOrder, JpaPredicate, JpaWindow, Expression...) */ - JpaExpression percentileDisc(JpaOrder order, JpaPredicate filter, Expression argument); + JpaExpression percentileDisc( + Expression argument, + JpaPredicate filter, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence); /** - * Create a {@code rank} ordered set-aggregate function expression. - * - * @param order order by clause used in within group - * @param argument argument to the function - * - * @return ordered set-aggregate expression - * - * @see #rank(JpaOrder, JpaPredicate, Expression) rank + * @see #rank(JpaOrder, JpaPredicate, JpaWindow, Expression...) */ - JpaExpression rank(JpaOrder order, Expression argument); + JpaExpression rank(JpaOrder order, Expression... arguments); + + /** + * @see #rank(JpaOrder, JpaPredicate, JpaWindow, Expression...) + */ + JpaExpression rank(JpaOrder order, JpaPredicate filter, Expression... arguments); + + /** + * @see #rank(JpaOrder, JpaPredicate, JpaWindow, Expression...) + */ + JpaExpression rank(JpaOrder order, JpaWindow window, Expression... arguments); /** * Create a {@code rank} ordered set-aggregate function expression. * * @param order order by clause used in within group * @param filter optional filter clause - * @param argument argument to the function + * @param window optional window over which to apply the function + * @param arguments arguments to the function * * @return ordered set-aggregate expression * * @see #functionWithinGroup */ - JpaExpression rank(JpaOrder order, JpaPredicate filter, Expression argument); + JpaExpression rank(JpaOrder order, JpaPredicate filter, JpaWindow window, Expression... arguments); /** - * Create a {@code percent_rank} ordered set-aggregate function expression. - * - * @param order order by clause used in within group - * @param argument argument to the function - * - * @return ordered set-aggregate expression - * - * @see #percentRank(JpaOrder, JpaPredicate, Expression) percentRank + * @see #percentRank(JpaOrder, JpaPredicate, JpaWindow, Expression...) */ - JpaExpression percentRank(JpaOrder order, Expression argument); + JpaExpression percentRank(JpaOrder order, Expression... arguments); + + /** + * @see #percentRank(JpaOrder, JpaPredicate, JpaWindow, Expression...) + */ + JpaExpression percentRank(JpaOrder order, JpaPredicate filter, Expression... arguments); + + /** + * @see #percentRank(JpaOrder, JpaPredicate, JpaWindow, Expression...) + */ + JpaExpression percentRank(JpaOrder order, JpaWindow window, Expression... arguments); /** * Create a {@code percent_rank} ordered set-aggregate function expression. * * @param order order by clause used in within group * @param filter optional filter clause - * @param argument argument to the function + * @param window optional window over which to apply the function + * @param arguments arguments to the function * * @return ordered set-aggregate expression * * @see #functionWithinGroup */ - JpaExpression percentRank(JpaOrder order, JpaPredicate filter, Expression argument); + JpaExpression percentRank( + JpaOrder order, + JpaPredicate filter, + JpaWindow window, + Expression... arguments); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/spi/HibernateCriteriaBuilderDelegate.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/spi/HibernateCriteriaBuilderDelegate.java index b649161e6c..478526da44 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/spi/HibernateCriteriaBuilderDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/spi/HibernateCriteriaBuilderDelegate.java @@ -1281,6 +1281,11 @@ public JpaExpression lastValue(Expression argument, JpaWindow window) return criteriaBuilder.lastValue( argument, window ); } + @Override + public JpaExpression nthValue(Expression argument, int n, JpaWindow window) { + return criteriaBuilder.nthValue( argument, n, window ); + } + @Override public JpaExpression nthValue(Expression argument, Expression n, JpaWindow window) { return criteriaBuilder.nthValue( argument, n, window ); @@ -1306,6 +1311,11 @@ public JpaExpression cumeDist(JpaWindow window) { return criteriaBuilder.cumeDist( window ); } + @Override + public JpaExpression functionWithinGroup(String name, Class type, JpaOrder order, Expression... args) { + return criteriaBuilder.functionWithinGroup( name, type, order, args ); + } + @Override public JpaExpression functionWithinGroup( String name, @@ -1317,8 +1327,29 @@ public JpaExpression functionWithinGroup( } @Override - public JpaExpression functionWithinGroup(String name, Class type, JpaOrder order, Expression... args) { - return criteriaBuilder.functionWithinGroup( name, type, order, args ); + public JpaExpression functionWithinGroup( + String name, + Class type, + JpaOrder order, + JpaWindow window, + Expression... args) { + return criteriaBuilder.functionWithinGroup( name, type, order, window, args ); + } + + @Override + public JpaExpression functionWithinGroup( + String name, + Class type, + JpaOrder order, + JpaPredicate filter, + JpaWindow window, + Expression... args) { + return criteriaBuilder.functionWithinGroup( name, type, order, filter, window, args ); + } + + @Override + public JpaExpression listagg(JpaOrder order, Expression argument, String separator) { + return criteriaBuilder.listagg( order, argument, separator ); } @Override @@ -1326,6 +1357,15 @@ public JpaExpression listagg(JpaOrder order, Expression argument return criteriaBuilder.listagg( order, argument, separator ); } + @Override + public JpaExpression listagg( + JpaOrder order, + JpaPredicate filter, + Expression argument, + String separator) { + return criteriaBuilder.listagg( order, filter, argument, separator ); + } + @Override public JpaExpression listagg( JpaOrder order, @@ -1336,58 +1376,197 @@ public JpaExpression listagg( } @Override - public JpaExpression mode(JpaOrder order, Expression argument) { - return criteriaBuilder.mode( order, argument ); + public JpaExpression listagg( + JpaOrder order, + JpaWindow window, + Expression argument, + String separator) { + return criteriaBuilder.listagg( order, window, argument, separator ); } @Override - public JpaExpression mode(JpaOrder order, JpaPredicate filter, Expression argument) { - return criteriaBuilder.mode( order, filter, argument ); + public JpaExpression listagg( + JpaOrder order, + JpaWindow window, + Expression argument, + Expression separator) { + return criteriaBuilder.listagg( order, window, argument, separator ); } @Override - public JpaExpression percentileCont(JpaOrder order, Expression argument) { - return criteriaBuilder.percentileCont( order, argument ); - } - - @Override - public JpaExpression percentileCont( + public JpaExpression listagg( JpaOrder order, JpaPredicate filter, - Expression argument) { - return criteriaBuilder.percentileCont( order, filter, argument ); + JpaWindow window, + Expression argument, + String separator) { + return criteriaBuilder.listagg( order, filter, window, argument, separator ); } @Override - public JpaExpression percentileDisc(JpaOrder order, Expression argument) { - return criteriaBuilder.percentileDisc( order, argument ); - } - - @Override - public JpaExpression percentileDisc( + public JpaExpression listagg( JpaOrder order, JpaPredicate filter, - Expression argument) { - return criteriaBuilder.percentileDisc( order, filter, argument ); + JpaWindow window, + Expression argument, + Expression separator) { + return criteriaBuilder.listagg( order, filter, window, argument, separator ); } @Override - public JpaExpression rank(JpaOrder order, Expression argument) { - return criteriaBuilder.rank( order, argument ); + public JpaExpression mode(Expression sortExpression, SortOrder sortOrder, NullPrecedence nullPrecedence) { + return criteriaBuilder.mode( sortExpression, sortOrder, nullPrecedence ); } @Override - public JpaExpression rank(JpaOrder order, JpaPredicate filter, Expression argument) { - return criteriaBuilder.rank( order, filter, argument ); + public JpaExpression mode( + JpaPredicate filter, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return criteriaBuilder.mode( filter, sortExpression, sortOrder, nullPrecedence ); } @Override - public JpaExpression percentRank(JpaOrder order, Expression argument) { - return criteriaBuilder.percentRank( order, argument ); + public JpaExpression mode( + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return criteriaBuilder.mode( window, sortExpression, sortOrder, nullPrecedence ); } @Override - public JpaExpression percentRank(JpaOrder order, JpaPredicate filter, Expression argument) { - return criteriaBuilder.percentRank( order, filter, argument ); + public JpaExpression mode( + JpaPredicate filter, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return criteriaBuilder.mode( filter, window, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + public JpaExpression percentileCont( + Expression argument, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return criteriaBuilder.percentileCont( argument, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + public JpaExpression percentileCont( + Expression argument, + JpaPredicate filter, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return criteriaBuilder.percentileCont( argument, filter, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + public JpaExpression percentileCont( + Expression argument, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return criteriaBuilder.percentileCont( argument, window, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + public JpaExpression percentileCont( + Expression argument, + JpaPredicate filter, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return criteriaBuilder.percentileCont( argument, filter, window, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + public JpaExpression percentileDisc( + Expression argument, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return criteriaBuilder.percentileDisc( argument, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + public JpaExpression percentileDisc( + Expression argument, + JpaPredicate filter, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return criteriaBuilder.percentileDisc( argument, filter, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + public JpaExpression percentileDisc( + Expression argument, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return criteriaBuilder.percentileDisc( argument, window, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + public JpaExpression percentileDisc( + Expression argument, + JpaPredicate filter, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return criteriaBuilder.percentileDisc( argument, filter, window, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + public JpaExpression rank(JpaOrder order, Expression... arguments) { + return criteriaBuilder.rank( order, arguments ); + } + + @Override + public JpaExpression rank(JpaOrder order, JpaPredicate filter, Expression... arguments) { + return criteriaBuilder.rank( order, filter, arguments ); + } + + @Override + public JpaExpression rank(JpaOrder order, JpaWindow window, Expression... arguments) { + return criteriaBuilder.rank( order, window, arguments ); + } + + @Override + public JpaExpression rank(JpaOrder order, JpaPredicate filter, JpaWindow window, Expression... arguments) { + return criteriaBuilder.rank( order, filter, window, arguments ); + } + + @Override + public JpaExpression percentRank(JpaOrder order, Expression... arguments) { + return criteriaBuilder.percentRank( order, arguments ); + } + + @Override + public JpaExpression percentRank(JpaOrder order, JpaPredicate filter, Expression... arguments) { + return criteriaBuilder.percentRank( order, filter, arguments ); + } + + @Override + public JpaExpression percentRank(JpaOrder order, JpaWindow window, Expression... arguments) { + return criteriaBuilder.percentRank( order, window, arguments ); + } + + @Override + public JpaExpression percentRank( + JpaOrder order, + JpaPredicate filter, + JpaWindow window, + Expression... arguments) { + return criteriaBuilder.percentRank( order, filter, window, arguments ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java index 0f501d2968..615059d955 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java @@ -2606,6 +2606,11 @@ public SqmExpression lastValue(Expression argument, JpaWindow window) return (SqmExpression) windowFunction( "last_value", argument.getJavaType(), window, argument ); } + @Override + public SqmExpression nthValue(Expression argument, int n, JpaWindow window) { + return nthValue( argument, value( n ), window ); + } + @Override @SuppressWarnings("unchecked") public SqmExpression nthValue(Expression argument, Expression n, JpaWindow window) { @@ -2635,6 +2640,11 @@ public SqmExpression cumeDist(JpaWindow window) { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Ordered set-aggregate functions + @Override + public SqmExpression functionWithinGroup(String name, Class type, JpaOrder order, Expression... args) { + return functionWithinGroup( name, type, order, null, null, args ); + } + @Override public SqmExpression functionWithinGroup( String name, @@ -2642,15 +2652,33 @@ public SqmExpression functionWithinGroup( JpaOrder order, JpaPredicate filter, Expression... args) { - // todo marco : we could also pass a Window (?) - // set aggregate function support OVER clauses - // eg. https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions110.htm + return functionWithinGroup( name, type, order, filter, null, args ); + } + + @Override + public SqmExpression functionWithinGroup( + String name, + Class type, + JpaOrder order, + JpaWindow window, + Expression... args) { + return functionWithinGroup( name, type, order, null, window, args ); + } + + @Override + public SqmExpression functionWithinGroup( + String name, + Class type, + JpaOrder order, + JpaPredicate filter, + JpaWindow window, + Expression... args) { SqmOrderByClause withinGroupClause = new SqmOrderByClause(); if ( order != null ) { withinGroupClause.addSortSpecification( (SqmSortSpecification) order ); } SqmPredicate sqmFilter = filter != null ? (SqmPredicate) filter : null; - return getFunctionDescriptor( name ).generateOrderedSetAggregateSqmExpression( + SqmExpression function = getFunctionDescriptor( name ).generateOrderedSetAggregateSqmExpression( expressionList( args ), sqmFilter, withinGroupClause, @@ -2658,20 +2686,31 @@ public SqmExpression functionWithinGroup( queryEngine, getJpaMetamodel().getTypeConfiguration() ); + if ( window == null ) { + return function; + } + else { + return new SqmOver<>( function, (SqmWindow) window ); + } } @Override - public SqmExpression functionWithinGroup( - String name, - Class type, + public SqmExpression listagg(JpaOrder order, Expression argument, String separator) { + return listagg( order, null, null, argument, separator ); + } + + @Override + public SqmExpression listagg(JpaOrder order, Expression argument, Expression separator) { + return listagg( order, null, null, argument, separator ); + } + + @Override + public SqmExpression listagg( JpaOrder order, - Expression... args) { - return functionWithinGroup( name, type, order, null, args ); - } - - @Override - public JpaExpression listagg(JpaOrder order, Expression argument, Expression separator) { - return listagg( order, null, argument, separator ); + JpaPredicate filter, + Expression argument, + String separator) { + return listagg( order, filter, null, argument, separator ); } @Override @@ -2680,62 +2719,223 @@ public SqmExpression listagg( JpaPredicate filter, Expression argument, Expression separator) { - return functionWithinGroup( "listagg", String.class, order, filter, argument, separator ); + return listagg( order, filter, null, argument, separator ); } @Override - public JpaExpression mode(JpaOrder order, Expression argument) { - return mode( order, null, argument ); + public SqmExpression listagg( + JpaOrder order, + JpaWindow window, + Expression argument, + String separator) { + return listagg( order, null, window, argument, separator ); } @Override - public SqmExpression mode(JpaOrder order, JpaPredicate filter, Expression argument) { - return functionWithinGroup( "mode", argument.getJavaType(), order, filter, argument ); + public SqmExpression listagg( + JpaOrder order, + JpaWindow window, + Expression argument, + Expression separator) { + return listagg( order, null, window, argument, separator ); } @Override - public JpaExpression percentileCont(JpaOrder order, Expression argument) { - return percentileCont( order, null, argument ); - } - - @Override - public SqmExpression percentileCont( + public SqmExpression listagg( JpaOrder order, JpaPredicate filter, - Expression argument) { - return functionWithinGroup( "percentile_cont", Integer.class, order, filter, argument ); + JpaWindow window, + Expression argument, + String separator) { + return listagg( order, filter, window, argument, value( separator, (SqmExpression) argument ) ); } @Override - public JpaExpression percentileDisc(JpaOrder order, Expression argument) { - return percentileDisc( order, null, argument ); - } - - @Override - public SqmExpression percentileDisc( + public SqmExpression listagg( JpaOrder order, JpaPredicate filter, - Expression argument) { - return functionWithinGroup( "percentile_disc", Integer.class, order, filter, argument ); + JpaWindow window, + Expression argument, + Expression separator) { + return functionWithinGroup( "listagg", String.class, order, filter, window, argument, separator ); } @Override - public JpaExpression rank(JpaOrder order, Expression argument) { - return rank( order, null, argument ); + public SqmExpression mode(Expression sortExpression, SortOrder sortOrder, NullPrecedence nullPrecedence) { + return mode( null, null, sortExpression, sortOrder, nullPrecedence ); } @Override - public SqmExpression rank(JpaOrder order, JpaPredicate filter, Expression argument) { - return functionWithinGroup( "rank", Long.class, order, filter, argument ); + public SqmExpression mode( + JpaPredicate filter, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return mode( filter, null, sortExpression, sortOrder, nullPrecedence ); } @Override - public JpaExpression percentRank(JpaOrder order, Expression argument) { - return percentRank( order, null, argument ); + public SqmExpression mode( + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return mode( null, window, sortExpression, sortOrder, nullPrecedence ); } @Override - public SqmExpression percentRank(JpaOrder order, JpaPredicate filter, Expression argument) { - return functionWithinGroup( "percent_rank", Double.class, order, filter, argument ); + @SuppressWarnings("unchecked") + public SqmExpression mode( + JpaPredicate filter, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return (SqmExpression) functionWithinGroup( + "mode", + sortExpression.getJavaType(), + sort( (SqmExpression) sortExpression, sortOrder, nullPrecedence ), + filter, + window + ); + } + + @Override + public SqmExpression percentileCont( + Expression argument, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return percentileCont( argument, null, null, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + public SqmExpression percentileCont( + Expression argument, + JpaPredicate filter, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return percentileCont( argument, filter, null, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + public SqmExpression percentileCont( + Expression argument, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return percentileCont( argument, null, window, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + @SuppressWarnings("unchecked") + public SqmExpression percentileCont( + Expression argument, + JpaPredicate filter, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return (SqmExpression) functionWithinGroup( + "percentile_cont", + sortExpression.getJavaType(), + sort( (SqmExpression) sortExpression, sortOrder, nullPrecedence ), + filter, + window, + argument + ); + } + + @Override + public SqmExpression percentileDisc( + Expression argument, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return percentileDisc( argument, null, null, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + public SqmExpression percentileDisc( + Expression argument, + JpaPredicate filter, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return percentileDisc( argument, filter, null, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + public SqmExpression percentileDisc( + Expression argument, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return percentileDisc( argument, null, window, sortExpression, sortOrder, nullPrecedence ); + } + + @Override + @SuppressWarnings("unchecked") + public SqmExpression percentileDisc( + Expression argument, + JpaPredicate filter, + JpaWindow window, + Expression sortExpression, + SortOrder sortOrder, + NullPrecedence nullPrecedence) { + return (SqmExpression) functionWithinGroup( + "percentile_disc", + sortExpression.getJavaType(), + sort( (SqmExpression) sortExpression, sortOrder, nullPrecedence ), + filter, + argument + ); + } + + @Override + public SqmExpression rank(JpaOrder order, Expression... arguments) { + return functionWithinGroup( "rank", Long.class, order, null, null, arguments ); + } + + @Override + public SqmExpression rank(JpaOrder order, JpaPredicate filter, Expression... arguments) { + return functionWithinGroup( "rank", Long.class, order, filter, null, arguments ); + } + + @Override + public SqmExpression rank(JpaOrder order, JpaWindow window, Expression... arguments) { + return functionWithinGroup( "rank", Long.class, order, null, window, arguments ); + } + + @Override + public SqmExpression rank(JpaOrder order, JpaPredicate filter, JpaWindow window, Expression... arguments) { + return functionWithinGroup( "rank", Long.class, order, filter, window, arguments ); + } + + @Override + public SqmExpression percentRank(JpaOrder order, Expression... arguments) { + return percentRank( order, null, null, arguments ); + } + + @Override + public SqmExpression percentRank(JpaOrder order, JpaPredicate filter, Expression... arguments) { + return percentRank( order, filter, null, arguments ); + } + + @Override + public SqmExpression percentRank(JpaOrder order, JpaWindow window, Expression... arguments) { + return percentRank( order, null, window, arguments ); + } + + @Override + public SqmExpression percentRank( + JpaOrder order, + JpaPredicate filter, + JpaWindow window, + Expression... arguments) { + return functionWithinGroup( "percent_rank", Double.class, order, filter, window, arguments ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaOrderedSetAggregateTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaOrderedSetAggregateTest.java index 27ad620469..5b61c7ed7a 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaOrderedSetAggregateTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaOrderedSetAggregateTest.java @@ -12,6 +12,9 @@ import org.hibernate.query.criteria.HibernateCriteriaBuilder; import org.hibernate.query.criteria.JpaExpression; +import org.hibernate.query.criteria.JpaWindow; +import org.hibernate.query.sqm.NullPrecedence; +import org.hibernate.query.sqm.SortOrder; import org.hibernate.testing.orm.domain.StandardDomainModel; import org.hibernate.testing.orm.domain.gambit.EntityOfBasics; @@ -107,7 +110,7 @@ public void testListaggWithoutOrder(SessionFactoryScope scope) { CriteriaQuery cr = cb.createQuery( String.class ); Root root = cr.from( EntityOfBasics.class ); - JpaExpression function = cb.listagg( null, root.get( "theString" ), cb.literal( "," ) ); + JpaExpression function = cb.listagg( null, root.get( "theString" ), "," ); cr.select( function ); List elements = Arrays.asList( session.createQuery( cr ).getSingleResult().split( "," ) ); @@ -126,11 +129,7 @@ public void testListagg(SessionFactoryScope scope) { CriteriaQuery cr = cb.createQuery( String.class ); Root root = cr.from( EntityOfBasics.class ); - JpaExpression function = cb.listagg( - cb.desc( root.get( "id" ) ), - root.get( "theString" ), - cb.literal( "," ) - ); + JpaExpression function = cb.listagg( cb.desc( root.get( "id" ) ), root.get( "theString" ), "," ); cr.select( function ); String result = session.createQuery( cr ).getSingleResult(); @@ -150,7 +149,7 @@ public void testListaggWithFilter(SessionFactoryScope scope) { cb.desc( root.get( "id" ) ), cb.lt( root.get( "theInt" ), cb.literal( 10 ) ), root.get( "theString" ), - cb.literal( "," ) + "," ); cr.select( function ); @@ -188,8 +187,10 @@ public void testInverseDistribution(SessionFactoryScope scope) { Root root = cr.from( EntityOfBasics.class ); JpaExpression function = cb.percentileDisc( - cb.asc( root.get( "theInt" ) ), - cb.literal( 0.5 ) + cb.literal( 0.5 ), + root.get( "theInt" ), + SortOrder.ASCENDING, + NullPrecedence.FIRST ); cr.select( function ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaWindowFunctionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaWindowFunctionTest.java index bd81d9a5a9..fa4b667c29 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaWindowFunctionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaWindowFunctionTest.java @@ -167,7 +167,7 @@ public void testNthValue(SessionFactoryScope scope) { JpaWindow window = cb.createWindow().orderBy( cb.desc( root.get( "theInt" ) ) ); JpaExpression nthValue = cb.nthValue( root.get( "theInt" ), - cb.literal( 2 ), + 2, window ); @@ -243,8 +243,7 @@ public void testReusableWindow(SessionFactoryScope scope) { public void testSumWithFilterAsWindowFunction(SessionFactoryScope scope) { scope.inTransaction( session -> { - // todo marco : add filter clause predicate to CriteriaBuilder ? - // problem with getting the window functions as aggregate, @see SqmCriteriaNodeBuilder#windowFunction + // todo marco : add 'simple` aggregate functions (sum, avg, count) TypedQuery q = session.createQuery( "select sum(eob.theInt) filter (where eob.theInt > 5) over (order by eob.theInt) from EntityOfBasics eob order by eob.theInt", Long.class