From aa9654696ff7d18bb0a44d63a595421cc34cf409 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Tue, 26 Mar 2024 23:55:46 +0100 Subject: [PATCH 1/2] fully incorporate id(this) into JDQL With suggestions from code review Co-authored-by: Nathan Rauh --- .../jakarta/data/repository/BasicRepository.java | 13 +++++++++++++ spec/src/antlr/JDQL.g4 | 13 +++++++++---- spec/src/main/asciidoc/query-language.asciidoc | 11 ++++++++++- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/jakarta/data/repository/BasicRepository.java b/api/src/main/java/jakarta/data/repository/BasicRepository.java index 933237ed8..47960e8cf 100644 --- a/api/src/main/java/jakarta/data/repository/BasicRepository.java +++ b/api/src/main/java/jakarta/data/repository/BasicRepository.java @@ -148,6 +148,19 @@ public interface BasicRepository extends DataRepository { @Find Optional findById(@By(ID) K id); + /** + * Retrieves the entities with the given unique identifiers. + * The returned list of entities is sorted by unique identifier + * in ascending order. If any of the unique identifiers is not + * found in the database, the returned list will be smaller + * than the supplied list of unique identifiers. + * + * @param ids a list of unique identifiers. + * @return the entities with the given unique identifiers. + */ + @Query("where id(this) in :ids order by id(this)") + List findByIdIn(@Param("ids") List ids); + /** * Retrieves all persistent entities of the specified type from the database. * diff --git a/spec/src/antlr/JDQL.g4 b/spec/src/antlr/JDQL.g4 index b6d2e359b..43d4198f1 100644 --- a/spec/src/antlr/JDQL.g4 +++ b/spec/src/antlr/JDQL.g4 @@ -13,15 +13,15 @@ where_clause : 'WHERE' conditional_expression; set_clause : 'SET' update_item (',' update_item)*; update_item : state_field_path_expression '=' (scalar_expression | 'NULL'); -select_clause : 'SELECT' select_list; -select_list +select_clause : 'SELECT' select_item; +select_item : state_field_path_expression + | id_expression | aggregate_expression ; -aggregate_expression : 'COUNT' '(' 'THIS' ')'; orderby_clause : 'ORDER' 'BY' orderby_item (',' orderby_item)*; -orderby_item : state_field_path_expression ('ASC' | 'DESC'); +orderby_item : (state_field_path_expression | id_expression) ('ASC' | 'DESC'); conditional_expression // highest to lowest precedence @@ -58,12 +58,17 @@ scalar_expression primary_expression : function_expression | special_expression + | id_expression | state_field_path_expression | enum_literal | input_parameter | literal ; +id_expression : 'ID' '(' 'THIS' ')' ; + +aggregate_expression : 'COUNT' '(' 'THIS' ')'; + function_expression : 'ABS' '(' scalar_expression ')' | 'LENGTH' '(' scalar_expression ')' diff --git a/spec/src/main/asciidoc/query-language.asciidoc b/spec/src/main/asciidoc/query-language.asciidoc index 209c0489b..e12f4a37b 100644 --- a/spec/src/main/asciidoc/query-language.asciidoc +++ b/spec/src/main/asciidoc/query-language.asciidoc @@ -146,6 +146,10 @@ When a path expression is executed, each element of the path is evaluated in tur If any element of a path expression evaluates to a null value, the whole path expression evaluates to a null value. +==== Identifier expressions + +An _identifier expression_, with syntax given by `id_expression`, is assigned the type of the unique identifier of the queried entity and evaluates to the unique identifier of a given record. An identifier expression is a synonym for a path expression with one element matching the identifier property of the queried entity type. An identifier expression may occur in the `select` clause, in the `order` clause, or as a scalar expression in the `where` clause. + ==== Function calls A _function call_ is the name of a JDQL function, followed by a parenthesized list of argument expressions, with syntax given by `function_expression`. @@ -354,7 +358,12 @@ The `where` clause is always optional. When it is missing, there is no restricti The `select` clause, with syntax given by `select_clause`, specifies a path expression which determines the values returned by the query. The path expression is evaluated for each record which satisfies the restriction imposed by the `where` clause, as specified in <>, and the value of the last element of the path expression is added to the query results. -Alternatively, the `select` clause may contain a single `count(this)` aggregate expression, which evaluates to the number of records which satisfy the restriction. A query beginning with `select count(this)` always returns a single result of type `Long`, no matter how many records satisfy the conditional expression in the `where` clause. +Alternatively, the `select` clause may contain either: + +- a single `count(this)` aggregate expression, which evaluates to the number of records which satisfy the restriction, or +- a single <>, which evaluates to the unique identifier of each record. + + A query beginning with `select count(this)` always returns a single result of type `Long`, no matter how many records satisfy the conditional expression in the `where` clause. NOTE: If a datastore does not natively provide the ability to count query results, the Jakarta Data provider is strongly encouraged, but not required, to implement this operation by counting the query results in Java. From ae82df2bb42d58a7bcd0d396aa103da21c3ea81b Mon Sep 17 00:00:00 2001 From: Gavin King Date: Wed, 20 Nov 2024 20:52:04 +0100 Subject: [PATCH 2/2] Update api/src/main/java/jakarta/data/repository/BasicRepository.java Co-authored-by: Nathan Rauh --- .../jakarta/data/repository/BasicRepository.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/api/src/main/java/jakarta/data/repository/BasicRepository.java b/api/src/main/java/jakarta/data/repository/BasicRepository.java index 47960e8cf..933237ed8 100644 --- a/api/src/main/java/jakarta/data/repository/BasicRepository.java +++ b/api/src/main/java/jakarta/data/repository/BasicRepository.java @@ -148,19 +148,6 @@ public interface BasicRepository extends DataRepository { @Find Optional findById(@By(ID) K id); - /** - * Retrieves the entities with the given unique identifiers. - * The returned list of entities is sorted by unique identifier - * in ascending order. If any of the unique identifiers is not - * found in the database, the returned list will be smaller - * than the supplied list of unique identifiers. - * - * @param ids a list of unique identifiers. - * @return the entities with the given unique identifiers. - */ - @Query("where id(this) in :ids order by id(this)") - List findByIdIn(@Param("ids") List ids); - /** * Retrieves all persistent entities of the specified type from the database. *