[
https://issues.apache.org/jira/browse/CAY-2816?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Andrus Adamchik updated CAY-2816:
---------------------------------
Description:
h2. Background
Currently, the syntax for (NOT) EXISTS requires two queries and an explicit
correlation expression:
https://cayenne.apache.org/docs/4.2/cayenne-guide/#subqueries
https://twitter.com/ApacheCayenne/status/1562702875327082496
This is great for a general case, but often the "enclosing" expression is
simply a relationship from top query root to subquery root. So the syntax can
be drastically simplifed, replacing sub ObjectSelect with a simple expression.
So this:
{noformat}
ObjectSelect<Painting> subQuery = ObjectSelect.query(Painting.class)
.where(Painting.ARTIST.eq(Artist.ARTIST_ID_PK_PROPERTY.enclosing()));
long count = ObjectSelect.query(Artist.class)
.where(ExpressionFactory.notExists(subQuery))
.selectCount(context);
{noformat}
becomes this:
{noformat}
long count = ObjectSelect.query(Artist.class)
.where(ExpressionFactory.notExists(Artist.PAINTINGS))
.selectCount(context);
{noformat}
or even better, this:
{noformat}
long count = ObjectSelect.query(Artist.class)
.where(Artist.PAINTINGS.notExists())
.selectCount(context);
{noformat}
h2. Task Scope
_(TODO: break to subtasks?)_
* Implement "ExpressionFactory.exists(Exp)" and
"ExpressionFactory.notExists(Exp)". The trick would be to check all paths
within the Exp and build the corresponding correlation expressions for the
subquery. It may potentially resolve to multiple subqueries (if multiple
relationships are specified), or no subqueries (for conditions based on the
root query attributes: 'not exists name = "A"' would become 'not (name = "A")'
in SQL)
* Implement parseable exp syntax "exists <exp>" and "not exists <exp>"
* Implement "exp.exists()" and "exp.notExists()" for fluent syntax
was:
h2. Background
Currently, the syntax for (NOT) EXISTS requires two queries and an explicit
correlation expression:
https://cayenne.apache.org/docs/4.2/cayenne-guide/#subqueries
https://twitter.com/ApacheCayenne/status/1562702875327082496
This is great for a general case, but often the "enclosing" expression is
simply a relationship from top query root to subquery root. So the syntax can
be drastically simplifed, replacing sub ObjectSelect with a simple expression.
So this:
{noformat}
ObjectSelect<Painting> subQuery = ObjectSelect.query(Painting.class)
.where(Painting.TO_ARTIST.eq(Artist.ARTIST_ID_PK_PROPERTY.enclosing()));
long count = ObjectSelect.query(Artist.class)
.where(ExpressionFactory.notExists(subQuery))
.selectCount(context);
{noformat}
becomes this:
{noformat}
long count = ObjectSelect.query(Artist.class)
.where(ExpressionFactory.notExists(Artist.PAINTINGS))
.selectCount(context);
{noformat}
or even better, this:
{noformat}
long count = ObjectSelect.query(Artist.class)
.where(Artist.PAINTINGS.notExists())
.selectCount(context);
{noformat}
h2. Task Scope
_(TODO: break to subtasks?)_
* Implement "ExpressionFactory.exists(Exp)" and
"ExpressionFactory.notExists(Exp)". The trick would be to check all paths
within the Exp and build the corresponding correlation expressions for the
subquery. It may potentially resolve to multiple subqueries (if multiple
relationships are specified), or no subqueries (for conditions based on the
root query attributes: 'not exists name = "A"' would become 'not (name = "A")'
in SQL)
* Implement parseable exp syntax "exists <exp>" and "not exists <exp>"
* Implement "exp.exists()" and "exp.notExists()" for fluent syntax
> (NOT) EXIST usability - provide simple expression syntax
> --------------------------------------------------------
>
> Key: CAY-2816
> URL: https://issues.apache.org/jira/browse/CAY-2816
> Project: Cayenne
> Issue Type: Improvement
> Reporter: Andrus Adamchik
> Assignee: Nikita Timofeev
> Priority: Major
> Fix For: 5.0.M1
>
>
> h2. Background
> Currently, the syntax for (NOT) EXISTS requires two queries and an explicit
> correlation expression:
> https://cayenne.apache.org/docs/4.2/cayenne-guide/#subqueries
> https://twitter.com/ApacheCayenne/status/1562702875327082496
> This is great for a general case, but often the "enclosing" expression is
> simply a relationship from top query root to subquery root. So the syntax can
> be drastically simplifed, replacing sub ObjectSelect with a simple
> expression. So this:
> {noformat}
> ObjectSelect<Painting> subQuery = ObjectSelect.query(Painting.class)
> .where(Painting.ARTIST.eq(Artist.ARTIST_ID_PK_PROPERTY.enclosing()));
> long count = ObjectSelect.query(Artist.class)
> .where(ExpressionFactory.notExists(subQuery))
> .selectCount(context);
> {noformat}
> becomes this:
> {noformat}
> long count = ObjectSelect.query(Artist.class)
> .where(ExpressionFactory.notExists(Artist.PAINTINGS))
> .selectCount(context);
> {noformat}
> or even better, this:
> {noformat}
> long count = ObjectSelect.query(Artist.class)
> .where(Artist.PAINTINGS.notExists())
> .selectCount(context);
> {noformat}
> h2. Task Scope
> _(TODO: break to subtasks?)_
> * Implement "ExpressionFactory.exists(Exp)" and
> "ExpressionFactory.notExists(Exp)". The trick would be to check all paths
> within the Exp and build the corresponding correlation expressions for the
> subquery. It may potentially resolve to multiple subqueries (if multiple
> relationships are specified), or no subqueries (for conditions based on the
> root query attributes: 'not exists name = "A"' would become 'not (name =
> "A")' in SQL)
> * Implement parseable exp syntax "exists <exp>" and "not exists <exp>"
> * Implement "exp.exists()" and "exp.notExists()" for fluent syntax
--
This message was sent by Atlassian Jira
(v8.20.10#820010)