Skip to content

Commit 1c01488

Browse files
committed
CAY-2863 DbEntity qualifiers are no longer applied to JOIN conditions
1 parent 9f051bc commit 1c01488

File tree

5 files changed

+54
-1
lines changed

5 files changed

+54
-1
lines changed

cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DbPathProcessor.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ protected void processNormalAttribute(String next) {
6363
return;
6464
}
6565

66+
// special case when the path should be processed in the context of the current join clause
67+
if(TableTree.CURRENT_ALIAS.equals(next)) {
68+
entity = context.getTableTree().nonNullActiveNode().getEntity();
69+
appendCurrentPath(next);
70+
return;
71+
}
72+
6673
throw new IllegalStateException("Unable to resolve path: " + currentDbPath.toString() + "." + next);
6774
}
6875

cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,10 @@ private Node processPathTranslationResult(Expression node, Expression parentNode
247247
return new EmptyNode();
248248
} else {
249249
String alias = context.getTableTree().aliasForPath(result.getLastAttributePath());
250+
// special case when the path should be processed in the context of the current join clause
251+
if(TableTree.CURRENT_ALIAS.equals(alias)) {
252+
alias = context.getTableTree().nonNullActiveNode().getTableAlias();
253+
}
250254
return table(alias).column(result.getLastAttribute()).build();
251255
}
252256
}

cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/TableTree.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
* @since 4.2
3535
*/
3636
class TableTree {
37+
38+
static final String CURRENT_ALIAS = "__current_join_table";
39+
3740
/**
3841
* Tables mapped by db path it's spawned by.
3942
* Can be following:
@@ -47,6 +50,7 @@ class TableTree {
4750

4851
private final TableTreeNode rootNode;
4952

53+
private TableTreeNode activeNode;
5054
private int tableAliasSequence;
5155

5256
TableTree(DbEntity root, TableTree parentTree) {
@@ -74,6 +78,9 @@ String aliasForPath(String attributePath) {
7478
if(Util.isEmptyString(attributePath)) {
7579
return rootNode.getTableAlias();
7680
}
81+
if(CURRENT_ALIAS.equals(attributePath)) {
82+
return CURRENT_ALIAS;
83+
}
7784
TableTreeNode node = tableNodes.get(attributePath);
7885
if (node == null) {
7986
throw new CayenneRuntimeException("No table for attribute '%s' found", attributePath);
@@ -98,6 +105,17 @@ String nextTableAlias() {
98105
return 't' + String.valueOf(tableAliasSequence++);
99106
}
100107

108+
TableTreeNode nonNullActiveNode() {
109+
if(activeNode == null) {
110+
throw new CayenneRuntimeException("No active TableTree node found");
111+
}
112+
return activeNode;
113+
}
114+
115+
void setActiveNode(TableTreeNode activeNode) {
116+
this.activeNode = activeNode;
117+
}
118+
101119
public int getNodeCount() {
102120
return tableNodes.size() + 1;
103121
}

cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/TableTreeStage.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,10 @@ private static ExpressionNodeBuilder appendQualifier(ExpressionNodeBuilder joinB
9393
}
9494

9595
dbQualifier = translateToDbPath(node, dbQualifier);
96+
// mark table tree node as current to process qualifier
97+
context.getTableTree().setActiveNode(node);
9698
Node translatedQualifier = context.getQualifierTranslator().translate(dbQualifier);
99+
context.getTableTree().setActiveNode(null);
97100
return joinBuilder.and(() -> translatedQualifier);
98101
}
99102

@@ -102,8 +105,11 @@ static Expression translateToDbPath(TableTreeNode node, Expression dbQualifier)
102105
dbQualifier = dbQualifier.transform(input -> {
103106
if (input instanceof ASTPath) {
104107
String path = ((ASTPath) input).getPath();
108+
// we do not really care about the parent path, as we do not need to join any new table here.
109+
// so we must tell the path processor that we are processing exactly this table
110+
// TODO: should check qualifiers via related tables if that is even the thing
105111
if(!pathToRoot.isEmpty()) {
106-
path = pathToRoot + '.' + path;
112+
path = TableTree.CURRENT_ALIAS + '.' + path;
107113
}
108114
return new ASTDbPath(path);
109115
}

cayenne-server/src/test/java/org/apache/cayenne/CDOQualifiedEntitiesIT.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,13 @@ private void createReadToOneDataSet() throws Exception {
101101
private void createJoinDataSet() throws Exception {
102102
tQualified3.insert(1, "O1", null);
103103
tQualified3.insert(2, "O2", accessStackAdapter.supportsBoolean() ? true : 1);
104+
tQualified3.insert(3, "11", null);
105+
tQualified3.insert(4, "12", accessStackAdapter.supportsBoolean() ? true : 1);
104106

105107
tQualified4.insert(1, "SHOULD_SELECT", null, 1);
106108
tQualified4.insert(2, "SHOULD_NOT_SELECT", null, 2);
109+
tQualified4.insert(3, "SHOULD_SELECT_TOO", null, 3);
110+
tQualified4.insert(4, "SHOULD_NOT_SELECT_TOO", null, 4);
107111
}
108112

109113
@Test
@@ -229,6 +233,20 @@ public void joinWithQualifier() throws Exception {
229233
assertEquals("SHOULD_SELECT", result.get(0).getName());
230234
}
231235

236+
@Test
237+
public void joinWithQualifierAndAliases() throws Exception {
238+
createJoinDataSet();
239+
240+
List<Qualified4> result = ObjectSelect.query(Qualified4.class)
241+
.where(Qualified4.QUALIFIED3.alias("a1").dot(Qualified3.NAME).like("O%"))
242+
.or(Qualified4.QUALIFIED3.alias("a2").dot(Qualified3.NAME).like("1%"))
243+
.select(context);
244+
245+
assertEquals(2, result.size());
246+
assertEquals("SHOULD_SELECT", result.get(0).getName());
247+
assertEquals("SHOULD_SELECT_TOO", result.get(1).getName());
248+
}
249+
232250
@Test
233251
public void joinWithCustomDbQualifier() throws Exception {
234252
createJoinDataSet();

0 commit comments

Comments
 (0)