This is an automated email from the ASF dual-hosted git repository. ntimofeev pushed a commit to branch 5.0-FIX-CAY-2844-joint-prefetch+qualifier in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit c5ee6520b352f2221c3d3055f050cc1c42fbefda Author: Nikita Timofeev <stari...@gmail.com> AuthorDate: Tue Mar 5 08:47:25 2024 +0400 CAY-2844 joint prefetch with ObjEntity qualifier --- .../cayenne/access/translator/select/PathProcessor.java | 3 +++ .../access/translator/select/PrefetchNodeStage.java | 16 +++++++++++----- .../cayenne/access/translator/select/TableTree.java | 3 +-- .../translator/select/TableTreeQualifierStage.java | 17 ++++++----------- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/PathProcessor.java b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/PathProcessor.java index 2f4712cbe..3854a5fba 100644 --- a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/PathProcessor.java +++ b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/PathProcessor.java @@ -62,6 +62,9 @@ abstract class PathProcessor<T extends Entity<?,?,?>> implements PathTranslation } public PathTranslationResult process(CayennePath path) { + if(path.marker() != CayennePath.NO_MARKER) { + currentDbPath = currentDbPath.withMarker(path.marker()); + } List<CayennePathSegment> segments = path.segments(); int size = segments.size(); for (int i = 0; i < size; i++) { diff --git a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/PrefetchNodeStage.java b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/PrefetchNodeStage.java index 836bbaca8..accabd374 100644 --- a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/PrefetchNodeStage.java +++ b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/PrefetchNodeStage.java @@ -26,7 +26,6 @@ import org.apache.cayenne.exp.path.CayennePath; import org.apache.cayenne.exp.Expression; import org.apache.cayenne.exp.ExpressionFactory; import org.apache.cayenne.exp.parser.ASTDbPath; -import org.apache.cayenne.exp.parser.ASTPath; import org.apache.cayenne.exp.path.CayennePathSegment; import org.apache.cayenne.map.DbAttribute; import org.apache.cayenne.map.DbEntity; @@ -86,7 +85,7 @@ class PrefetchNodeStage implements TranslationStage { ASTDbPath dbPrefetch = (ASTDbPath) objEntity.translateToDbPath(prefetchExp); CayennePath dbPath = dbPrefetch.getPath(); DbEntity dbEntity = objEntity.getDbEntity(); - Expression targetQualifier = targetRel.getTargetEntity().getDeclaredQualifier(); + Expression targetQualifier = context.getResolver().getClassDescriptor(targetRel.getTargetEntityName()).getEntityInheritanceTree().qualifierForEntityAndSubclasses(); CayennePath fullPath = CayennePath.EMPTY_PATH.withMarker(CayennePath.PREFETCH_MARKER); @@ -98,10 +97,10 @@ class PrefetchNodeStage implements TranslationStage { fullPath = fullPath.dot(c); if(targetQualifier != null && c == dbPath.last()) { - targetQualifier = targetRel.getTargetEntity().translateToDbPath(targetQualifier); - context.getTableTree().addJoinTable(fullPath.withModifier(CayennePath.PREFETCH), rel, JoinType.LEFT_OUTER, targetQualifier); + targetQualifier = translateToPrefetchQualifier(targetRel.getTargetEntity(), targetQualifier); + context.getTableTree().addJoinTable(fullPath.withMarker(CayennePath.PREFETCH_MARKER), rel, JoinType.LEFT_OUTER, targetQualifier); } else { - context.getTableTree().addJoinTable(fullPath.withModifier(CayennePath.PREFETCH), rel, JoinType.LEFT_OUTER); + context.getTableTree().addJoinTable(fullPath.withMarker(CayennePath.PREFETCH_MARKER), rel, JoinType.LEFT_OUTER); } dbEntity = rel.getTargetEntity(); } @@ -123,6 +122,13 @@ class PrefetchNodeStage implements TranslationStage { } } + Expression translateToPrefetchQualifier(ObjEntity entity, Expression targetQualifier) { + Expression expression = entity.translateToDbPath(targetQualifier); + return expression.transform(o -> o instanceof ASTDbPath + ? ExpressionFactory.dbPathExp(((ASTDbPath) o).getPath().withMarker(CayennePath.PREFETCH_MARKER)) + : o); + } + private void processPrefetchQuery(TranslatorContext context) { Select<?> select = context.getQuery().unwrap(); if(!(select instanceof PrefetchSelectQuery)) { diff --git a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/TableTree.java b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/TableTree.java index fe3f5fe26..87ab9bcd0 100644 --- a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/TableTree.java +++ b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/TableTree.java @@ -30,7 +30,6 @@ import org.apache.cayenne.exp.path.CayennePath; import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.map.DbRelationship; import org.apache.cayenne.map.JoinType; -import org.apache.cayenne.util.Util; /** * @since 4.2 @@ -61,7 +60,7 @@ class TableTree { addJoinTable(path, relationship, joinType, null); } - void addJoinTable(String path, DbRelationship relationship, JoinType joinType, Expression additionalQualifier) { + void addJoinTable(CayennePath path, DbRelationship relationship, JoinType joinType, Expression additionalQualifier) { TableTreeNode treeNode = tableNodes.get(path); if (treeNode != null) { return; diff --git a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/TableTreeQualifierStage.java b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/TableTreeQualifierStage.java index f75390398..313582ca8 100644 --- a/cayenne/src/main/java/org/apache/cayenne/access/translator/select/TableTreeQualifierStage.java +++ b/cayenne/src/main/java/org/apache/cayenne/access/translator/select/TableTreeQualifierStage.java @@ -19,16 +19,12 @@ package org.apache.cayenne.access.translator.select; -import org.apache.cayenne.access.sqlbuilder.NodeBuilder; import org.apache.cayenne.access.sqlbuilder.sqltree.Node; import org.apache.cayenne.exp.Expression; import org.apache.cayenne.exp.parser.ASTDbPath; import org.apache.cayenne.exp.parser.ASTPath; import org.apache.cayenne.exp.path.CayennePath; -import static org.apache.cayenne.access.sqlbuilder.SQLBuilder.exp; -import static org.apache.cayenne.access.sqlbuilder.SQLBuilder.node; - /** * @since 4.2 */ @@ -52,13 +48,12 @@ class TableTreeQualifierStage implements TranslationStage { } CayennePath pathToRoot = node.getAttributePath(); - dbQualifier = dbQualifier.transform(input -> { - if (input instanceof ASTPath) { - CayennePath path = pathToRoot.dot(((ASTPath) input).getPath()); - return new ASTDbPath(path); - } - return input; - }); + dbQualifier = dbQualifier.transform(input -> + // here we are not only marking path as prefetch, but changing ObjPath to DB (without ) + input instanceof ASTPath + ? new ASTDbPath(pathToRoot.dot(((ASTPath) input).getPath()).withMarker(CayennePath.PREFETCH_MARKER)) + : input + ); Node translatedQualifier = context.getQualifierTranslator().translate(dbQualifier); context.appendQualifierNode(translatedQualifier); }