You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2019/01/11 14:10:00 UTC
cayenne git commit: Regression in join logic in SelectTranslator
Repository: cayenne
Updated Branches:
refs/heads/master 835d1d451 -> 6bb83bbee
Regression in join logic in SelectTranslator
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/6bb83bbe
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/6bb83bbe
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/6bb83bbe
Branch: refs/heads/master
Commit: 6bb83bbee58254caaa0749c677a673ed84ef85ab
Parents: 835d1d4
Author: Nikita Timofeev <st...@gmail.com>
Authored: Fri Jan 11 17:09:52 2019 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Jan 11 17:09:52 2019 +0300
----------------------------------------------------------------------
.../translator/select/DbPathProcessor.java | 28 +++++++++++++-------
.../select/DescriptorColumnExtractor.java | 3 ++-
.../translator/select/ObjPathProcessor.java | 19 +++++++------
.../access/translator/select/PathProcessor.java | 6 ++++-
.../translator/select/PathTranslator.java | 8 ++++--
.../cayenne/exp/property/PathAliasesIT.java | 4 +--
.../apache/cayenne/query/ColumnSelectIT.java | 12 ++++-----
7 files changed, 51 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/6bb83bbe/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DbPathProcessor.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DbPathProcessor.java b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DbPathProcessor.java
index cccea12..383e1f9 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DbPathProcessor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DbPathProcessor.java
@@ -30,14 +30,22 @@ import org.apache.cayenne.map.JoinType;
*/
class DbPathProcessor extends PathProcessor<DbEntity> {
- DbPathProcessor(TranslatorContext context, DbEntity entity, String parentPath) {
+ private boolean flattenedPath;
+
+ DbPathProcessor(TranslatorContext context, DbEntity entity, String parentPath, boolean flattenedPath) {
super(context, entity);
+ this.flattenedPath = flattenedPath;
if(parentPath != null) {
currentDbPath.append(parentPath);
}
}
@Override
+ public boolean isOuterJoin() {
+ return super.isOuterJoin() || flattenedPath;
+ }
+
+ @Override
protected void processNormalAttribute(String next) {
DbAttribute dbAttribute = entity.getAttribute(next);
if(dbAttribute != null) {
@@ -76,7 +84,8 @@ class DbPathProcessor extends PathProcessor<DbEntity> {
processRelTermination(relationship);
} else {
appendCurrentPath(relationship.getName());
- context.getTableTree().addJoinTable(currentDbPath.toString(), relationship, JoinType.LEFT_OUTER);
+ context.getTableTree().addJoinTable(currentDbPath.toString(), relationship, isOuterJoin()
+ ? JoinType.LEFT_OUTER : JoinType.INNER);
if(!relationship.isToMany()) {
String path = currentDbPath.toString();
for (DbAttribute attribute : relationship.getTargetEntity().getPrimaryKeys()) {
@@ -86,20 +95,21 @@ class DbPathProcessor extends PathProcessor<DbEntity> {
}
}
- protected void processRelTermination(DbRelationship rel) {
- this.relationship = rel;
+ protected void processRelTermination(DbRelationship relationship) {
+ this.relationship = relationship;
String path = currentDbPath.toString();
- appendCurrentPath(rel.getName());
+ appendCurrentPath(relationship.getName());
- if (rel.isToMany() || !rel.isToPK()) {
+ if (relationship.isToMany() || !relationship.isToPK()) {
// match on target PK
- context.getTableTree().addJoinTable(currentDbPath.toString(), rel, JoinType.LEFT_OUTER);
+ context.getTableTree().addJoinTable(currentDbPath.toString(), relationship, isOuterJoin()
+ ? JoinType.LEFT_OUTER : JoinType.INNER);
path = currentDbPath.toString();
- for(DbAttribute attribute : rel.getTargetEntity().getPrimaryKeys()) {
+ for(DbAttribute attribute : relationship.getTargetEntity().getPrimaryKeys()) {
addAttribute(path, attribute);
}
} else {
- for(DbJoin join : rel.getJoins()) {
+ for(DbJoin join : relationship.getJoins()) {
addAttribute(path, join.getSource());
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/6bb83bbe/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractor.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractor.java b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractor.java
index 5bcff0f..43f521e 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/DescriptorColumnExtractor.java
@@ -99,7 +99,8 @@ class DescriptorColumnExtractor extends BaseColumnExtractor implements PropertyV
@Override
public boolean visitToOne(ToOneProperty property) {
ObjRelationship rel = property.getRelationship();
- PathTranslationResult result = pathTranslator.translatePath(rel.getSourceEntity(), property.getName(), prefix);
+ // outer join should be used for to-one relationships
+ PathTranslationResult result = pathTranslator.translatePath(rel.getSourceEntity(), property.getName() + '+', prefix);
int count = result.getDbAttributes().size();
for(int i=0; i<count; i++) {
http://git-wip-us.apache.org/repos/asf/cayenne/blob/6bb83bbe/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/ObjPathProcessor.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/ObjPathProcessor.java b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/ObjPathProcessor.java
index 111bfc4..9bf98db 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/ObjPathProcessor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/ObjPathProcessor.java
@@ -89,8 +89,10 @@ class ObjPathProcessor extends PathProcessor<ObjEntity> {
return;
}
- PathTranslationResult result = context.getPathTranslator()
- .translatePath(entity.getDbEntity(), attribute.getDbAttributePath(), currentDbPath.toString());
+ PathTranslationResult result = context.getPathTranslator().translatePath(entity.getDbEntity()
+ , attribute.getDbAttributePath()
+ , currentDbPath.toString()
+ , attribute.isFlattened());
attributes.addAll(result.getDbAttributes());
attributePaths.addAll(result.getAttributePaths());
relationship = result.getDbRelationship().orElse(relationship);
@@ -109,22 +111,23 @@ class ObjPathProcessor extends PathProcessor<ObjEntity> {
for (int i=0; i<count; i++) {
DbRelationship dbRel = relationship.getDbRelationships().get(i);
appendCurrentPath(dbRel.getName());
+ boolean leftJoin = isOuterJoin() || count > 1;
context.getTableTree().addJoinTable(currentDbPath.toString(), dbRel,
- isOuterJoin ? JoinType.LEFT_OUTER : JoinType.INNER);
+ leftJoin ? JoinType.LEFT_OUTER : JoinType.INNER);
}
}
}
- protected void processRelTermination(ObjRelationship rel) {
- String path = currentAlias != null ? currentAlias : rel.getDbRelationshipPath();
- if(isOuterJoin) {
+ protected void processRelTermination(ObjRelationship relationship) {
+ String path = currentAlias != null ? currentAlias : relationship.getDbRelationshipPath();
+ if(isOuterJoin()) {
path += OUTER_JOIN_INDICATOR;
}
PathTranslationResult result = context.getPathTranslator()
- .translatePath(entity.getDbEntity(), path, currentDbPath.toString());
+ .translatePath(entity.getDbEntity(), path, currentDbPath.toString(), relationship.isFlattened());
attributes.addAll(result.getDbAttributes());
attributePaths.addAll(result.getAttributePaths());
- relationship = result.getDbRelationship().orElse(relationship);
+ this.relationship = result.getDbRelationship().orElse(this.relationship);
currentDbPath.delete(0, currentDbPath.length());
currentDbPath.append(result.getFinalPath());
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/6bb83bbe/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/PathProcessor.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/PathProcessor.java b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/PathProcessor.java
index b330608..bb9f1d2 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/PathProcessor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/PathProcessor.java
@@ -44,7 +44,7 @@ abstract class PathProcessor<T extends Entity> implements PathTranslationResult
protected final StringBuilder currentDbPath;
protected boolean lastComponent;
- protected boolean isOuterJoin;
+ private boolean isOuterJoin;
protected T entity;
protected DbRelationship relationship;
protected String currentAlias;
@@ -126,4 +126,8 @@ abstract class PathProcessor<T extends Entity> implements PathTranslationResult
currentDbPath.append(OUTER_JOIN_INDICATOR);
}
}
+
+ public boolean isOuterJoin() {
+ return isOuterJoin;
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/6bb83bbe/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/PathTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/PathTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/PathTranslator.java
index c3dd57f..dfaf8ce 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/PathTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/PathTranslator.java
@@ -48,9 +48,13 @@ class PathTranslator {
return translatePath(entity, path, null);
}
- PathTranslationResult translatePath(DbEntity entity, String path, String parentPath) {
+ PathTranslationResult translatePath(DbEntity entity, String path, String parentPath, boolean flattenedPath) {
return dbResultCache.computeIfAbsent(parentPath + '.' + entity.getName() + '.' + path,
- (k) -> new DbPathProcessor(context, entity, parentPath).process(path));
+ (k) -> new DbPathProcessor(context, entity, parentPath, flattenedPath).process(path));
+ }
+
+ PathTranslationResult translatePath(DbEntity entity, String path, String parentPath) {
+ return translatePath(entity, path, parentPath, false);
}
PathTranslationResult translatePath(DbEntity entity, String path) {
http://git-wip-us.apache.org/repos/asf/cayenne/blob/6bb83bbe/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PathAliasesIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PathAliasesIT.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PathAliasesIT.java
index 93a68f2..b182dc5 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PathAliasesIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/property/PathAliasesIT.java
@@ -167,7 +167,7 @@ public class PathAliasesIT extends ServerCase {
List<Object[]> artistAndPaintingCount = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME, Artist.PAINTING_ARRAY.count())
.having(Artist.PAINTING_ARRAY.alias("p1").count().lt(5L))
.select(context);
- assertEquals(19, artistAndPaintingCount.size());
+ assertEquals(4, artistAndPaintingCount.size());
assertTrue((Long)artistAndPaintingCount.get(0)[1] < 5);
}
@@ -298,7 +298,7 @@ public class PathAliasesIT extends ServerCase {
List<Object[]> artistAndPaintingCount = ObjectSelect.columnQuery(Artist.class, Artist.ARTIST_NAME, Artist.PAINTING_ARRAY.count())
.having(PropertyFactory.createBase(e1, Number.class).count().lt(5L))
.select(context);
- assertEquals(19, artistAndPaintingCount.size());
+ assertEquals(4, artistAndPaintingCount.size());
assertTrue((Long)artistAndPaintingCount.get(0)[1] < 5);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/6bb83bbe/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
index cbd2e03..a7086ec 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
@@ -609,7 +609,7 @@ public class ColumnSelectIT extends ServerCase {
.pageSize(10)
.select(context);
assertNotNull(a);
- assertEquals(20, a.size());
+ assertEquals(5, a.size());
int idx = 0;
for(Object[] next : a) {
assertNotNull(next);
@@ -657,7 +657,7 @@ public class ColumnSelectIT extends ServerCase {
.pageSize(10)
.select(context);
assertNotNull(a);
- assertEquals(20, a.size());
+ assertEquals(5, a.size());
int idx = 0;
for(Object[] next : a) {
assertNotNull(next);
@@ -677,7 +677,7 @@ public class ColumnSelectIT extends ServerCase {
.select(context);
assertNotNull(a);
- assertEquals(36, a.size());
+ assertEquals(21, a.size());
int idx = 0;
for(Object[] next : a) {
assertNotNull(next);
@@ -782,7 +782,7 @@ public class ColumnSelectIT extends ServerCase {
}
private void checkAggregatePrefetchResults(List<Object[]> result) {
- assertEquals(20, result.size());
+ assertEquals(5, result.size());
for(Object[] next : result) {
assertTrue(next[0] instanceof Artist);
assertTrue(next[1] instanceof Long);
@@ -852,7 +852,7 @@ public class ColumnSelectIT extends ServerCase {
List<Object[]> result = ObjectSelect.query(Artist.class)
.columns(artistProperty, Artist.ARTIST_NAME, Artist.PAINTING_ARRAY.count())
.select(context);
- assertEquals(20, result.size());
+ assertEquals(5, result.size());
for(Object[] next : result) {
assertTrue(next[0] instanceof Artist);
@@ -903,7 +903,7 @@ public class ColumnSelectIT extends ServerCase {
List<Object[]> result = ObjectSelect.query(Artist.class)
.columns(artistProperty, Artist.PAINTING_ARRAY.flat(), Artist.PAINTING_ARRAY.dot(Painting.TO_GALLERY))
.select(context);
- assertEquals(36, result.size());
+ assertEquals(21, result.size());
for(Object[] next : result) {
assertTrue(next[0] instanceof Artist);