This is an automated email from the ASF dual-hosted git repository.

ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git


The following commit(s) were added to refs/heads/master by this push:
     new 69d754c24 Fix split expressions for db relationships
     new 598eb371e Merge pull request #540 from m-dzianishchyts/CAY-2764
69d754c24 is described below

commit 69d754c24be25506fcf8f0ccb64d179cecf5e005
Author: Mikhail Dzianishchyts <mikhail.dzianishch...@gmail.com>
AuthorDate: Mon Nov 21 02:58:17 2022 +0300

    Fix split expressions for db relationships
---
 .../access/translator/select/DbPathProcessor.java  |   1 +
 .../org/apache/cayenne/exp/ExpressionFactory.java  |  13 +-
 .../apache/cayenne/exp/ExpressionFactoryIT.java    | 308 ++++++++++++---------
 3 files changed, 186 insertions(+), 136 deletions(-)

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 48fdcee2c..c1336b5ff 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
@@ -70,6 +70,7 @@ class DbPathProcessor extends PathProcessor<DbEntity> {
             throw new IllegalStateException("Non-relationship aliased path 
part: " + alias);
         }
 
+        entity = relationship.getTargetEntity();
         processRelationship(relationship);
     }
 
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java
index 8f50603f7..b17775411 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/ExpressionFactory.java
@@ -79,6 +79,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
 
 /**
  * Helper class to build expressions.
@@ -330,6 +331,14 @@ public class ExpressionFactory {
                        return new ASTTrue();
                }
 
+               Function<Object, ASTPath> pathProvider;
+               if (path.startsWith(ASTDbPath.DB_PREFIX)) {
+                       pathProvider = ASTDbPath::new;
+                       path = path.substring(ASTDbPath.DB_PREFIX.length());
+               } else {
+                       pathProvider = ASTObjPath::new;
+               }
+
                int split = path.indexOf(SPLIT_SEPARATOR);
 
                List<Expression> matches = new ArrayList<>(values.length);
@@ -355,13 +364,13 @@ public class ExpressionFactory {
                                String aliasedPath = beforeSplit + alias + 
afterSplit;
                                i++;
 
-                               ASTPath pathExp = new ASTObjPath(aliasedPath);
+                               ASTPath pathExp = 
pathProvider.apply(aliasedPath);
                                
pathExp.setPathAliases(Collections.singletonMap(alias, splitChunk));
                                matches.add(new ASTEqual(pathExp, value));
                        }
                } else {
                        for (Object value : values) {
-                               matches.add(new ASTEqual(new ASTObjPath(path), 
value));
+                               matches.add(new 
ASTEqual(pathProvider.apply(path), value));
                        }
                }
 
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/exp/ExpressionFactoryIT.java 
b/cayenne-server/src/test/java/org/apache/cayenne/exp/ExpressionFactoryIT.java
index c22b71d46..22408c316 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/exp/ExpressionFactoryIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/exp/ExpressionFactoryIT.java
@@ -19,21 +19,11 @@
 
 package org.apache.cayenne.exp;
 
-import static org.apache.cayenne.exp.ExpressionFactory.exp;
-import static org.apache.cayenne.exp.ExpressionFactory.greaterExp;
-import static org.apache.cayenne.exp.FunctionExpressionFactory.lengthExp;
-import static org.apache.cayenne.exp.FunctionExpressionFactory.substringExp;
-import static org.apache.cayenne.exp.FunctionExpressionFactory.trimExp;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.testdo.testmap.Gallery;
 import org.apache.cayenne.testdo.testmap.Painting;
 import org.apache.cayenne.unit.UnitDbAdapter;
 import org.apache.cayenne.unit.di.server.CayenneProjects;
@@ -41,130 +31,180 @@ import org.apache.cayenne.unit.di.server.ServerCase;
 import org.apache.cayenne.unit.di.server.UseServerRuntime;
 import org.junit.Test;
 
+import java.util.List;
+
+import static org.apache.cayenne.exp.ExpressionFactory.exp;
+import static org.apache.cayenne.exp.ExpressionFactory.greaterExp;
+import static org.apache.cayenne.exp.FunctionExpressionFactory.lengthExp;
+import static org.apache.cayenne.exp.FunctionExpressionFactory.substringExp;
+import static org.apache.cayenne.exp.FunctionExpressionFactory.trimExp;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
 @UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
 public class ExpressionFactoryIT extends ServerCase {
 
-       @Inject
-       private ObjectContext context;
-
-       @Inject
-       private UnitDbAdapter accessStackAdapter;
-
-       // CAY-416
-       @Test
-       public void testCollectionMatch() {
-               Artist artist = context.newObject(Artist.class);
-               artist.setArtistName("artist");
-               Painting p1 = context.newObject(Painting.class),
-                               p2 = context.newObject(Painting.class),
-                               p3 = context.newObject(Painting.class);
-               p1.setPaintingTitle("p1");
-               p2.setPaintingTitle("p2");
-               p3.setPaintingTitle("p3");
-               artist.addToPaintingArray(p1);
-               artist.addToPaintingArray(p2);
-
-               context.commitChanges();
-
-               assertTrue(ExpressionFactory.matchExp("paintingArray", 
p1).match(artist));
-               assertFalse(ExpressionFactory.matchExp("paintingArray", 
p3).match(artist));
-               assertTrue(ExpressionFactory.noMatchExp("paintingArray", 
p1).match(artist)); // changed to align with SQL
-               assertTrue(ExpressionFactory.noMatchExp("paintingArray", 
p3).match(artist));
-
-               
assertTrue(ExpressionFactory.matchExp("paintingArray.paintingTitle", 
"p1").match(artist));
-               
assertFalse(ExpressionFactory.matchExp("paintingArray.paintingTitle", 
"p3").match(artist));
-               
assertTrue(ExpressionFactory.noMatchExp("paintingArray.paintingTitle", 
"p1").match(artist)); // changed to align with SQL
-               
assertTrue(ExpressionFactory.noMatchExp("paintingArray.paintingTitle", 
"p3").match(artist));
-
-               assertTrue(ExpressionFactory.inExp("paintingTitle", 
"p1").match(p1));
-               assertFalse(ExpressionFactory.notInExp("paintingTitle", 
"p3").match(p3));
-       }
-
-       @Test
-       public void testIn() {
-               Artist a1 = context.newObject(Artist.class);
-               a1.setArtistName("a1");
-               Painting p1 = context.newObject(Painting.class);
-               p1.setPaintingTitle("p1");
-               Painting p2 = context.newObject(Painting.class);
-               p2.setPaintingTitle("p2");
-               a1.addToPaintingArray(p1);
-               a1.addToPaintingArray(p2);
-
-               Expression in = ExpressionFactory.inExp("paintingArray", p1);
-               assertTrue(in.match(a1));
-       }
-
-       @Test
-       public void testEscapeCharacter() {
-               if(!accessStackAdapter.supportsEscapeInLike()) {
-                       return;
-               }
-
-               Artist a1 = context.newObject(Artist.class);
-               a1.setArtistName("A_1");
-               Artist a2 = context.newObject(Artist.class);
-               a2.setArtistName("A_2");
-               context.commitChanges();
-
-               Expression ex1 = 
ExpressionFactory.likeIgnoreCaseDbExp("ARTIST_NAME", "A*_1", '*');
-               List<Artist> artists = ObjectSelect.query(Artist.class, 
ex1).select(context);
-               assertEquals(1, artists.size());
-
-               Expression ex2 = ExpressionFactory.likeExp("artistName", 
"A*_2", '*');
-               artists = ObjectSelect.query(Artist.class, ex2).select(context);
-               assertEquals(1, artists.size());
-       }
-       
-       @Test
-       public void testContains_Escape() {
-
-               if(!accessStackAdapter.supportsEscapeInLike()) {
-                       return;
-               }
-
-               Artist a1 = context.newObject(Artist.class);
-               a1.setArtistName("MA_1X");
-               Artist a2 = context.newObject(Artist.class);
-               a2.setArtistName("CA%2Y");
-               context.commitChanges();
-
-               Expression ex1 = 
ExpressionFactory.containsExp(Artist.ARTIST_NAME.getName(), "A_1");
-               List<Artist> artists = ObjectSelect.query(Artist.class, 
ex1).select(context);
-               assertEquals(1, artists.size());
-
-               Expression ex2 = 
ExpressionFactory.containsExp(Artist.ARTIST_NAME.getName(), "A%2");
-               artists = ObjectSelect.query(Artist.class, ex2).select(context);
-               assertEquals(1, artists.size());
-       }
-
-       @Test
-       public void testDifferentExpressionAPI() {
-               List<Artist> res;
-
-               // First version via expression string
-               Expression exp1 = exp(
-                               "length(substring(artistName, 1, 3)) > 
length(trim(artistName))"
-               );
-               res = ObjectSelect.query(Artist.class, exp1).select(context);
-               assertEquals(0, res.size());
-
-               // Second version via FunctionExpressionFactory API
-               Expression exp2 = greaterExp(
-                               
lengthExp(substringExp(Artist.ARTIST_NAME.getExpression(), 1, 3)),
-                               
lengthExp(trimExp(Artist.ARTIST_NAME.getExpression()))
-               );
-               res = ObjectSelect.query(Artist.class, exp2).select(context);
-               assertEquals(0, res.size());
-
-               // Third version via Property API
-               Expression exp3 = Artist.ARTIST_NAME.substring(1, 3).length()
-                               .gt(Artist.ARTIST_NAME.trim().length());
-               res = ObjectSelect.query(Artist.class, exp3).select(context);
-               assertEquals(0, res.size());
-
-               // Check that all expressions are equal
-               assertEquals(exp1, exp2);
-               assertEquals(exp3, exp3);
-       }
+    @Inject
+    private ObjectContext context;
+
+    @Inject
+    private UnitDbAdapter accessStackAdapter;
+
+    // CAY-416
+    @Test
+    public void testCollectionMatch() {
+        Artist artist = context.newObject(Artist.class);
+        artist.setArtistName("artist");
+        Painting p1 = context.newObject(Painting.class),
+                p2 = context.newObject(Painting.class),
+                p3 = context.newObject(Painting.class);
+        p1.setPaintingTitle("p1");
+        p2.setPaintingTitle("p2");
+        p3.setPaintingTitle("p3");
+        artist.addToPaintingArray(p1);
+        artist.addToPaintingArray(p2);
+
+        context.commitChanges();
+
+        assertTrue(ExpressionFactory.matchExp("paintingArray", 
p1).match(artist));
+        assertFalse(ExpressionFactory.matchExp("paintingArray", 
p3).match(artist));
+        assertTrue(ExpressionFactory.noMatchExp("paintingArray", 
p1).match(artist)); // changed to align with SQL
+        assertTrue(ExpressionFactory.noMatchExp("paintingArray", 
p3).match(artist));
+
+        assertTrue(ExpressionFactory.matchExp("paintingArray.paintingTitle", 
"p1").match(artist));
+        assertFalse(ExpressionFactory.matchExp("paintingArray.paintingTitle", 
"p3").match(artist));
+        assertTrue(ExpressionFactory.noMatchExp("paintingArray.paintingTitle", 
"p1")
+                           .match(artist)); // changed to align with SQL
+        assertTrue(ExpressionFactory.noMatchExp("paintingArray.paintingTitle", 
"p3").match(artist));
+
+        assertTrue(ExpressionFactory.inExp("paintingTitle", "p1").match(p1));
+        assertFalse(ExpressionFactory.notInExp("paintingTitle", 
"p3").match(p3));
+    }
+
+    @Test
+    public void testIn() {
+        Artist a1 = context.newObject(Artist.class);
+        a1.setArtistName("a1");
+        Painting p1 = context.newObject(Painting.class);
+        p1.setPaintingTitle("p1");
+        Painting p2 = context.newObject(Painting.class);
+        p2.setPaintingTitle("p2");
+        a1.addToPaintingArray(p1);
+        a1.addToPaintingArray(p2);
+
+        Expression in = ExpressionFactory.inExp("paintingArray", p1);
+        assertTrue(in.match(a1));
+    }
+
+    @Test
+    public void testEscapeCharacter() {
+        if (!accessStackAdapter.supportsEscapeInLike()) {
+            return;
+        }
+
+        Artist a1 = context.newObject(Artist.class);
+        a1.setArtistName("A_1");
+        Artist a2 = context.newObject(Artist.class);
+        a2.setArtistName("A_2");
+        context.commitChanges();
+
+        Expression ex1 = ExpressionFactory.likeIgnoreCaseDbExp("ARTIST_NAME", 
"A*_1", '*');
+        List<Artist> artists = ObjectSelect.query(Artist.class, 
ex1).select(context);
+        assertEquals(1, artists.size());
+
+        Expression ex2 = ExpressionFactory.likeExp("artistName", "A*_2", '*');
+        artists = ObjectSelect.query(Artist.class, ex2).select(context);
+        assertEquals(1, artists.size());
+    }
+
+    @Test
+    public void testContains_Escape() {
+
+        if (!accessStackAdapter.supportsEscapeInLike()) {
+            return;
+        }
+
+        Artist a1 = context.newObject(Artist.class);
+        a1.setArtistName("MA_1X");
+        Artist a2 = context.newObject(Artist.class);
+        a2.setArtistName("CA%2Y");
+        context.commitChanges();
+
+        Expression ex1 = 
ExpressionFactory.containsExp(Artist.ARTIST_NAME.getName(), "A_1");
+        List<Artist> artists = ObjectSelect.query(Artist.class, 
ex1).select(context);
+        assertEquals(1, artists.size());
+
+        Expression ex2 = 
ExpressionFactory.containsExp(Artist.ARTIST_NAME.getName(), "A%2");
+        artists = ObjectSelect.query(Artist.class, ex2).select(context);
+        assertEquals(1, artists.size());
+    }
+
+    @Test
+    public void testSplitExpressions() {
+        Artist artist1 = context.newObject(Artist.class),
+                artist2 = context.newObject(Artist.class);
+        artist1.setArtistName("a1");
+        artist2.setArtistName("a2");
+
+        Painting p1 = context.newObject(Painting.class),
+                p2 = context.newObject(Painting.class),
+                p3 = context.newObject(Painting.class);
+        p1.setPaintingTitle("p1");
+        p2.setPaintingTitle("p2");
+        p3.setPaintingTitle("p3");
+
+        Gallery g1 = context.newObject(Gallery.class),
+                g2 = context.newObject(Gallery.class);
+        g1.setGalleryName("g1");
+        g2.setGalleryName("g2");
+
+        artist1.addToPaintingArray(p1);
+        artist1.addToPaintingArray(p2);
+        artist2.addToPaintingArray(p3);
+
+        g1.addToPaintingArray(p1);
+        g1.addToPaintingArray(p3);
+        g2.addToPaintingArray(p2);
+
+        context.commitChanges();
+
+        List<Artist> objArtists = ObjectSelect.query(Artist.class)
+                
.where(ExpressionFactory.matchAllExp("|paintingArray.toGallery.galleryName", 
"g1", "g2"))
+                .select(context);
+        List<Artist> dbArtists = ObjectSelect.query(Artist.class)
+                
.where(ExpressionFactory.matchAllExp("db:|paintingArray.toGallery.GALLERY_NAME",
 "g1", "g2"))
+                .select(context);
+        assertEquals(objArtists, dbArtists);
+    }
+
+    @Test
+    public void testDifferentExpressionAPI() {
+        List<Artist> res;
+
+        // First version via expression string
+        Expression exp1 = exp(
+                "length(substring(artistName, 1, 3)) > 
length(trim(artistName))"
+        );
+        res = ObjectSelect.query(Artist.class, exp1).select(context);
+        assertEquals(0, res.size());
+
+        // Second version via FunctionExpressionFactory API
+        Expression exp2 = greaterExp(
+                lengthExp(substringExp(Artist.ARTIST_NAME.getExpression(), 1, 
3)),
+                lengthExp(trimExp(Artist.ARTIST_NAME.getExpression()))
+        );
+        res = ObjectSelect.query(Artist.class, exp2).select(context);
+        assertEquals(0, res.size());
+
+        // Third version via Property API
+        Expression exp3 = Artist.ARTIST_NAME.substring(1, 3).length()
+                .gt(Artist.ARTIST_NAME.trim().length());
+        res = ObjectSelect.query(Artist.class, exp3).select(context);
+        assertEquals(0, res.size());
+
+        // Check that all expressions are equal
+        assertEquals(exp1, exp2);
+        assertEquals(exp3, exp3);
+    }
 }

Reply via email to