Repository: cayenne
Updated Branches:
  refs/heads/STABLE-4.0 d0b88ba35 -> 2f472cea0


CAY-2389 DbEntity qualifier with DbPath expression translates into wrong SQL

(cherry picked from commit 41dd56c)


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/2f472cea
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/2f472cea
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/2f472cea

Branch: refs/heads/STABLE-4.0
Commit: 2f472cea08124149f1ac79b5072a96976a7a35a8
Parents: d0b88ba
Author: Nikita Timofeev <stari...@gmail.com>
Authored: Mon Dec 18 16:05:28 2017 +0300
Committer: Nikita Timofeev <stari...@gmail.com>
Committed: Mon Dec 18 16:05:28 2017 +0300

----------------------------------------------------------------------
 .../access/translator/select/JoinStack.java     |  8 +-
 .../apache/cayenne/CDOQualifiedEntitiesIT.java  | 81 ++++++++++++++++----
 .../cayenne/testdo/qualified/Qualified3.java    |  9 +++
 .../cayenne/testdo/qualified/Qualified4.java    |  9 +++
 .../testdo/qualified/auto/_Qualified3.java      | 43 +++++++++++
 .../testdo/qualified/auto/_Qualified4.java      | 38 +++++++++
 .../src/test/resources/qualified.map.xml        | 27 +++++++
 docs/doc/src/main/resources/RELEASE-NOTES.txt   |  1 +
 8 files changed, 198 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f472cea/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/JoinStack.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/JoinStack.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/JoinStack.java
index 5b11a3c..143546a 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/JoinStack.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/JoinStack.java
@@ -24,9 +24,7 @@ import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.QuotingStrategy;
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.parser.ASTDbPath;
-import org.apache.cayenne.exp.parser.ASTObjPath;
-import org.apache.cayenne.exp.parser.SimpleNode;
-import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.exp.parser.ASTPath;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbJoin;
 import org.apache.cayenne.map.DbRelationship;
@@ -212,8 +210,8 @@ public class JoinStack {
                }
 
                public Object transform(Object input) {
-                       if (input instanceof ASTObjPath) {
-                               return new ASTDbPath(pathToRoot.toString() + 
((SimpleNode) input).getOperand(0));
+                       if (input instanceof ASTPath) {
+                               return new ASTDbPath(pathToRoot.toString() + 
((ASTPath) input).getPath());
                        }
                        return input;
                }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f472cea/cayenne-server/src/test/java/org/apache/cayenne/CDOQualifiedEntitiesIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/CDOQualifiedEntitiesIT.java 
b/cayenne-server/src/test/java/org/apache/cayenne/CDOQualifiedEntitiesIT.java
index 729a1d8..be5f10d 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/CDOQualifiedEntitiesIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/CDOQualifiedEntitiesIT.java
@@ -19,11 +19,17 @@
 package org.apache.cayenne;
 
 import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.query.SelectQuery;
 import org.apache.cayenne.test.jdbc.DBHelper;
 import org.apache.cayenne.test.jdbc.TableHelper;
 import org.apache.cayenne.testdo.qualified.Qualified1;
 import org.apache.cayenne.testdo.qualified.Qualified2;
+import org.apache.cayenne.testdo.qualified.Qualified3;
+import org.apache.cayenne.testdo.qualified.Qualified4;
 import org.apache.cayenne.unit.UnitDbAdapter;
 import org.apache.cayenne.unit.di.server.CayenneProjects;
 import org.apache.cayenne.unit.di.server.ServerCase;
@@ -51,23 +57,28 @@ public class CDOQualifiedEntitiesIT extends ServerCase {
 
     private TableHelper tQualified1;
     private TableHelper tQualified2;
+    private TableHelper tQualified3;
+    private TableHelper tQualified4;
 
     @Before
     public void setUp() throws Exception {
         int bool = accessStackAdapter.supportsBoolean() ? Types.BOOLEAN : 
Types.INTEGER;
 
-        tQualified1 = new TableHelper(dbHelper, "TEST_QUALIFIED1");
-        tQualified1.setColumns("ID", "NAME", "DELETED").setColumnTypes(
-                Types.INTEGER,
-                Types.VARCHAR,
-                bool);
-
-        tQualified2 = new TableHelper(dbHelper, "TEST_QUALIFIED2");
-        tQualified2.setColumns("ID", "NAME", "DELETED", 
"QUALIFIED1_ID").setColumnTypes(
-                Types.INTEGER,
-                Types.VARCHAR,
-                bool,
-                Types.INTEGER);
+        tQualified1 = new TableHelper(dbHelper, "TEST_QUALIFIED1")
+                .setColumns("ID", "NAME", "DELETED")
+                .setColumnTypes(Types.INTEGER, Types.VARCHAR, bool);
+
+        tQualified2 = new TableHelper(dbHelper, "TEST_QUALIFIED2")
+                .setColumns("ID", "NAME", "DELETED", "QUALIFIED1_ID")
+                .setColumnTypes(Types.INTEGER, Types.VARCHAR, bool, 
Types.INTEGER);
+
+        tQualified3 = new TableHelper(dbHelper, "TEST_QUALIFIED3")
+                .setColumns("ID", "NAME", "DELETED")
+                .setColumnTypes(Types.INTEGER, Types.VARCHAR, bool);
+
+        tQualified4 = new TableHelper(dbHelper, "TEST_QUALIFIED4")
+                .setColumns("ID", "NAME", "DELETED", "QUALIFIED3_ID")
+                .setColumnTypes(Types.INTEGER, Types.VARCHAR, bool, 
Types.INTEGER);
     }
 
     private void createReadToManyDataSet() throws Exception {
@@ -88,6 +99,14 @@ public class CDOQualifiedEntitiesIT extends ServerCase {
         tQualified2.insert(1, "OY1", null, 2);
     }
 
+    private void createJoinDataSet() throws Exception {
+        tQualified3.insert(1, "O1", null);
+        tQualified3.insert(2, "O2", accessStackAdapter.supportsBoolean() ? 
true : 1);
+
+        tQualified4.insert(1, "SHOULD_SELECT", null, 1);
+        tQualified4.insert(2, "SHOULD_NOT_SELECT", null, 2);
+    }
+
     @Test
     public void testReadToMany() throws Exception {
         if (accessStackAdapter.supportsNullBoolean()) {
@@ -125,7 +144,43 @@ public class CDOQualifiedEntitiesIT extends ServerCase {
             assertEquals("OY1", root.getName());
 
             Qualified1 target = root.getQualified1();
-            assertNull("" + target, target);
+            assertNull(target);
+        }
+    }
+
+    @Test
+    public void joinWithQualifier() throws Exception {
+        createJoinDataSet();
+
+        List<Qualified4> result = ObjectSelect.query(Qualified4.class)
+                .where(Qualified4.QUALIFIED3.dot(Qualified3.NAME).like("O%"))
+                .select(context);
+
+        assertEquals(1, result.size());
+        assertEquals("SHOULD_SELECT", result.get(0).getName());
+    }
+
+    @Test
+    public void joinWithCustomDbQualifier() throws Exception {
+        createJoinDataSet();
+
+        DbEntity entity1 = 
context.getEntityResolver().getDbEntity("TEST_QUALIFIED3");
+        DbEntity entity2 = 
context.getEntityResolver().getDbEntity("TEST_QUALIFIED4");
+        Expression oldExpression1 = entity1.getQualifier();
+        Expression oldExpression2 = entity2.getQualifier();
+        try {
+            entity1.setQualifier(ExpressionFactory.matchDbExp("DELETED", 
null));
+            entity2.setQualifier(ExpressionFactory.matchDbExp("DELETED", 
null));
+
+            List<Qualified4> result = ObjectSelect.query(Qualified4.class)
+                    
.where(Qualified4.QUALIFIED3.dot(Qualified3.NAME).like("O%"))
+                    .select(context);
+
+            assertEquals(1, result.size());
+            assertEquals("SHOULD_SELECT", result.get(0).getName());
+        } finally {
+            entity1.setQualifier(oldExpression1);
+            entity2.setQualifier(oldExpression2);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f472cea/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/Qualified3.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/Qualified3.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/Qualified3.java
new file mode 100644
index 0000000..203481d
--- /dev/null
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/Qualified3.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.testdo.qualified;
+
+import org.apache.cayenne.testdo.qualified.auto._Qualified3;
+
+public class Qualified3 extends _Qualified3 {
+
+    private static final long serialVersionUID = 1L; 
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f472cea/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/Qualified4.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/Qualified4.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/Qualified4.java
new file mode 100644
index 0000000..a510a8c
--- /dev/null
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/Qualified4.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.testdo.qualified;
+
+import org.apache.cayenne.testdo.qualified.auto._Qualified4;
+
+public class Qualified4 extends _Qualified4 {
+
+    private static final long serialVersionUID = 1L; 
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f472cea/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified3.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified3.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified3.java
new file mode 100644
index 0000000..6ab1f9c
--- /dev/null
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified3.java
@@ -0,0 +1,43 @@
+package org.apache.cayenne.testdo.qualified.auto;
+
+import java.util.List;
+
+import org.apache.cayenne.CayenneDataObject;
+import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.testdo.qualified.Qualified4;
+
+/**
+ * Class _Qualified3 was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public abstract class _Qualified3 extends CayenneDataObject {
+
+    private static final long serialVersionUID = 1L; 
+
+    public static final String ID_PK_COLUMN = "ID";
+
+    public static final Property<String> NAME = Property.create("name", 
String.class);
+    public static final Property<List<Qualified4>> QUALIFIED4S = 
Property.create("qualified4s", List.class);
+
+    public void setName(String name) {
+        writeProperty("name", name);
+    }
+    public String getName() {
+        return (String)readProperty("name");
+    }
+
+    public void addToQualified4s(Qualified4 obj) {
+        addToManyTarget("qualified4s", obj, true);
+    }
+    public void removeFromQualified4s(Qualified4 obj) {
+        removeToManyTarget("qualified4s", obj, true);
+    }
+    @SuppressWarnings("unchecked")
+    public List<Qualified4> getQualified4s() {
+        return (List<Qualified4>)readProperty("qualified4s");
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f472cea/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified4.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified4.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified4.java
new file mode 100644
index 0000000..7a7742b
--- /dev/null
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified4.java
@@ -0,0 +1,38 @@
+package org.apache.cayenne.testdo.qualified.auto;
+
+import org.apache.cayenne.CayenneDataObject;
+import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.testdo.qualified.Qualified3;
+
+/**
+ * Class _Qualified4 was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public abstract class _Qualified4 extends CayenneDataObject {
+
+    private static final long serialVersionUID = 1L; 
+
+    public static final String ID_PK_COLUMN = "ID";
+
+    public static final Property<String> NAME = Property.create("name", 
String.class);
+    public static final Property<Qualified3> QUALIFIED3 = 
Property.create("qualified3", Qualified3.class);
+
+    public void setName(String name) {
+        writeProperty("name", name);
+    }
+    public String getName() {
+        return (String)readProperty("name");
+    }
+
+    public void setQualified3(Qualified3 qualified3) {
+        setToOneTarget("qualified3", qualified3, true);
+    }
+
+    public Qualified3 getQualified3() {
+        return (Qualified3)readProperty("qualified3");
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f472cea/cayenne-server/src/test/resources/qualified.map.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/qualified.map.xml 
b/cayenne-server/src/test/resources/qualified.map.xml
index 0a30f4a..1268569 100644
--- a/cayenne-server/src/test/resources/qualified.map.xml
+++ b/cayenne-server/src/test/resources/qualified.map.xml
@@ -16,6 +16,19 @@
                <db-attribute name="NAME" type="VARCHAR" length="200"/>
                <db-attribute name="QUALIFIED1_ID" type="INTEGER"/>
        </db-entity>
+       <db-entity name="TEST_QUALIFIED3">
+               <db-attribute name="DELETED" type="BOOLEAN"/>
+               <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true"/>
+               <db-attribute name="NAME" type="VARCHAR" length="200"/>
+               <qualifier><![CDATA[DELETED = null]]></qualifier>
+       </db-entity>
+       <db-entity name="TEST_QUALIFIED4">
+               <db-attribute name="DELETED" type="BOOLEAN"/>
+               <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true"/>
+               <db-attribute name="NAME" type="VARCHAR" length="200"/>
+               <db-attribute name="QUALIFIED3_ID" type="INTEGER"/>
+               <qualifier><![CDATA[DELETED = null]]></qualifier>
+       </db-entity>
        <obj-entity name="Qualified1" 
className="org.apache.cayenne.testdo.qualified.Qualified1" 
dbEntityName="TEST_QUALIFIED1">
                <qualifier><![CDATA[deleted = null]]></qualifier>
                <obj-attribute name="deleted" type="java.lang.Boolean" 
db-attribute-path="DELETED"/>
@@ -26,12 +39,26 @@
                <obj-attribute name="deleted" type="java.lang.Boolean" 
db-attribute-path="DELETED"/>
                <obj-attribute name="name" type="java.lang.String" 
db-attribute-path="NAME"/>
        </obj-entity>
+       <obj-entity name="Qualified3" 
className="org.apache.cayenne.testdo.qualified.Qualified3" 
dbEntityName="TEST_QUALIFIED3">
+               <obj-attribute name="name" type="java.lang.String" 
db-attribute-path="NAME"/>
+       </obj-entity>
+       <obj-entity name="Qualified4" 
className="org.apache.cayenne.testdo.qualified.Qualified4" 
dbEntityName="TEST_QUALIFIED4">
+               <obj-attribute name="name" type="java.lang.String" 
db-attribute-path="NAME"/>
+       </obj-entity>
        <db-relationship name="qualified2s" source="TEST_QUALIFIED1" 
target="TEST_QUALIFIED2" toMany="true">
                <db-attribute-pair source="ID" target="QUALIFIED1_ID"/>
        </db-relationship>
        <db-relationship name="qualified1" source="TEST_QUALIFIED2" 
target="TEST_QUALIFIED1" toMany="false">
                <db-attribute-pair source="QUALIFIED1_ID" target="ID"/>
        </db-relationship>
+       <db-relationship name="qualified4s" source="TEST_QUALIFIED3" 
target="TEST_QUALIFIED4" toMany="true">
+               <db-attribute-pair source="ID" target="QUALIFIED3_ID"/>
+       </db-relationship>
+       <db-relationship name="qualified3" source="TEST_QUALIFIED4" 
target="TEST_QUALIFIED3" toMany="false">
+               <db-attribute-pair source="QUALIFIED3_ID" target="ID"/>
+       </db-relationship>
        <obj-relationship name="qualified2s" source="Qualified1" 
target="Qualified2" db-relationship-path="qualified2s"/>
        <obj-relationship name="qualified1" source="Qualified2" 
target="Qualified1" db-relationship-path="qualified1"/>
+       <obj-relationship name="qualified4s" source="Qualified3" 
target="Qualified4" deleteRule="Deny" db-relationship-path="qualified4s"/>
+       <obj-relationship name="qualified3" source="Qualified4" 
target="Qualified3" deleteRule="Nullify" db-relationship-path="qualified3"/>
 </data-map>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f472cea/docs/doc/src/main/resources/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/docs/doc/src/main/resources/RELEASE-NOTES.txt 
b/docs/doc/src/main/resources/RELEASE-NOTES.txt
index f933cf2..2b8adbe 100644
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@ -23,6 +23,7 @@ CAY-2370 ValueObjectType for byte[] fails lookup
 CAY-2382 Lack of synchronization in DataContext serialization
 CAY-2387 Can't select byte[] property with ColumnSelect
 CAY-2388 Modeler: Visualization issues with undo/redo actions for attributes 
and relationships
+CAY-2389 DbEntity qualifier with DbPath expression translates into wrong SQL
 
 ----------------------------------
 Release: 4.0.B2

Reply via email to