From 3ec8b27b2a389b1211c412f36c906efb92071a2c Mon Sep 17 00:00:00 2001 From: Jan Schatteman Date: Wed, 4 Aug 2021 22:00:48 +0200 Subject: [PATCH] Added doc notes on the filter clause and the ilike predicate Signed-off-by: Jan Schatteman --- .../userguide/chapters/query/hql/HQL.adoc | 27 ++++++++++++++++++- .../query/hql/extras/predicate_ilike_bnf.txt | 4 +++ .../org/hibernate/userguide/hql/HQLTest.java | 16 +++++++++++ .../org/hibernate/grammars/hql/HqlParser.g4 | 27 +++++++++---------- 4 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/predicate_ilike_bnf.txt diff --git a/documentation/src/main/asciidoc/userguide/chapters/query/hql/HQL.adoc b/documentation/src/main/asciidoc/userguide/chapters/query/hql/HQL.adoc index 69706a7f32..6e116c133c 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/query/hql/HQL.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/query/hql/HQL.adoc @@ -1148,6 +1148,8 @@ The supported aggregate functions are: For floating point values (other than `BigDecimal`) the result type is `Double`. For `BigInteger` values, the result type is `BigInteger`. For `BigDecimal` values, the result type is `BigDecimal`. +Aggregations often appear with grouping. For information on grouping see <>. + [[hql-aggregate-functions-example]] .Aggregate function examples ==== @@ -1157,7 +1159,16 @@ include::{sourcedir}/HQLTest.java[tags=hql-aggregate-functions-example] ---- ==== -Aggregations often appear with grouping. For information on grouping see <>. +All of these aggregate functions also support the inclusion of a specific *filter clause* + +[[hql-aggregate-functions-filter-example]] +.Filter clause example +==== +[source, JAVA, indent=0] +---- +include::{sourcedir}/HQLTest.java[tags=hql-aggregate-functions-filter-example] +---- +==== [[hql-exp-functions]] === Scalar functions @@ -1780,6 +1791,20 @@ include::{sourcedir}/HQLTest.java[tags=hql-like-predicate-escape-example] ---- ==== +[[hql-ilike-predicate]] +=== Ilike predicate + +Performs a case-insensitive like comparison on string values. The syntax is: + +[[hql-ilike-predicate-bnf]] +[source, JAVA, indent=0] +---- +include::{extrasdir}/predicate_ilike_bnf.txt[] +---- + +The semantics are identical to those of the aforementioned <>, with the sole difference that the comparison is now case insensitive. + + [[hql-between-predicate]] === Between predicate diff --git a/documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/predicate_ilike_bnf.txt b/documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/predicate_ilike_bnf.txt new file mode 100644 index 0000000000..89ba9fce35 --- /dev/null +++ b/documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/predicate_ilike_bnf.txt @@ -0,0 +1,4 @@ +ilike_expression ::= + string_expression + [NOT] ILIKE pattern_value + [ESCAPE escape_character] diff --git a/documentation/src/test/java/org/hibernate/userguide/hql/HQLTest.java b/documentation/src/test/java/org/hibernate/userguide/hql/HQLTest.java index 9bff4d97de..120c866e75 100644 --- a/documentation/src/test/java/org/hibernate/userguide/hql/HQLTest.java +++ b/documentation/src/test/java/org/hibernate/userguide/hql/HQLTest.java @@ -1178,6 +1178,22 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase { }); } + @Test + public void test_hql_aggregate_functions_filter_example() { + doInJPA( this::entityManagerFactory, entityManager -> { + //tag::hql-aggregate-functions-filter-example[] + + List callCount = entityManager.createQuery( + "select p.number, count(c) filter(where c.duration < 30) " + + "from Call c " + + "join c.phone p " + + "group by p.number", Object[].class ) + .getResultList(); + //end::hql-aggregate-functions-filter-example[] + assertNotNull(callCount.get( 0 )); + }); + } + @Test @SkipForDialect(value = DerbyDialect.class, comment = "See https://issues.apache.org/jira/browse/DERBY-2072") public void test_hql_concat_function_example() { diff --git a/hibernate-core/src/main/antlr/org/hibernate/grammars/hql/HqlParser.g4 b/hibernate-core/src/main/antlr/org/hibernate/grammars/hql/HqlParser.g4 index b8fb00dc34..a5d5844f74 100644 --- a/hibernate-core/src/main/antlr/org/hibernate/grammars/hql/HqlParser.g4 +++ b/hibernate-core/src/main/antlr/org/hibernate/grammars/hql/HqlParser.g4 @@ -400,20 +400,20 @@ whereClause predicate //highest to lowest precedence - : LEFT_PAREN predicate RIGHT_PAREN # GroupedPredicate - | expression IS (NOT)? NULL # IsNullPredicate - | expression IS (NOT)? EMPTY # IsEmptyPredicate - | expression (NOT)? IN inList # InPredicate - | expression (NOT)? BETWEEN expression AND expression # BetweenPredicate - | expression (NOT)? (LIKE | ILIKE) expression (likeEscape)? # LikePredicate - | expression comparisonOperator expression # ComparisonPredicate + : LEFT_PAREN predicate RIGHT_PAREN # GroupedPredicate + | expression IS (NOT)? NULL # IsNullPredicate + | expression IS (NOT)? EMPTY # IsEmptyPredicate + | expression (NOT)? IN inList # InPredicate + | expression (NOT)? BETWEEN expression AND expression # BetweenPredicate + | expression (NOT)? (LIKE | ILIKE) expression (likeEscape)? # LikePredicate + | expression comparisonOperator expression # ComparisonPredicate | EXISTS (ELEMENTS|INDICES) LEFT_PAREN dotIdentifierSequence RIGHT_PAREN # ExistsCollectionPartPredicate - | EXISTSexpression # ExistsPredicate - | expression (NOT)? MEMBER OF path # MemberOfPredicate - | NOT predicate # NegatedPredicate - | predicate AND predicate # AndPredicate - | predicate OR predicate # OrPredicate - | expression # BooleanExpressionPredicate + | EXISTS expression # ExistsPredicate + | expression (NOT)? MEMBER OF path # MemberOfPredicate + | NOT predicate # NegatedPredicate + | predicate AND predicate # AndPredicate + | predicate OR predicate # OrPredicate + | expression # BooleanExpressionPredicate ; comparisonOperator @@ -1060,4 +1060,3 @@ identifier logUseOfReservedWordAsIdentifier( getCurrentToken() ); } ; -