Skip to content

Commit

Permalink
Optimize "(not) exists" exp on no-relationship path
Browse files Browse the repository at this point in the history
  • Loading branch information
m-dzianishchyts committed Feb 13, 2024
1 parent 95d9aaf commit 67fe671
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,28 @@ private Expression validateAndCleanup(ObjEntity entity, Expression exp) {
exp = pathCache.resolve(entity.getName(), ((ASTObjPath) exp).getPath()).getPathExp();
}

// process root ASTExits|ASTNotExists that can't be properly handled by ExpressionProcessor.
if (exp instanceof ASTExists || exp instanceof ASTNotExists) {
return optimizeExistsExp(exp);
}

return exp;
}

private ExpressionProcessor getOrCreateExpressionProcessor(ObjEntity entity) {
return postProcessors.computeIfAbsent(entity.getName(), e -> new ExpressionProcessor(entity));
}

private static Expression optimizeExistsExp(Expression exp) {
Expression pathExistExp = ((Expression) exp.getOperand(0));
if (pathExistExp instanceof ASTSubquery) {
return exp;
}
return exp instanceof ASTExists
? pathExistExp
: pathExistExp.notExp();
}

private class ExpressionProcessor extends TraversalHelper {

private final ObjEntity entity;
Expand Down Expand Up @@ -124,6 +139,9 @@ public void finishedChild(Expression parentNode, int childIndex, boolean hasMore
childIndex
);
}
if (childNode instanceof ASTExists || childNode instanceof ASTNotExists) {
parentNode.setOperand(childIndex, optimizeExistsExp((Expression) childNode));
}
}

@Override
Expand Down
23 changes: 23 additions & 0 deletions agrest-cayenne/src/test/java/io/agrest/cayenne/GET/ExpIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,29 @@ public void exists_Path_Relationship() {
.bodyEquals(3, "{\"id\":1}", "{\"id\":2}", "{\"id\":3}");
}

@Test
public void exists_Path_NoRelationship() {

tester.e2().insertColumns("id_", "name")
.values(1, "qwe")
.values(2, "try")
.exec();

tester.e3().insertColumns("id_", "name")
.values(1, "xxx")
.values(2, "yxy")
.values(3, null)
.exec();

tester.target("/e3")
.queryParam("include", "id")
.queryParam("exp", "exists name")
.queryParam("sort", "id")
.get()
.wasOk()
.bodyEquals(2, "{\"id\":1}", "{\"id\":2}");
}

@Test
public void like_MultiChar_Pattern_Escape() {

Expand Down

0 comments on commit 67fe671

Please sign in to comment.