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);
     }

Reply via email to