Repository: cayenne
Updated Branches:
  refs/heads/STABLE-3.1 52ad986a8 -> 71baa229d


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


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

Branch: refs/heads/STABLE-3.1
Commit: 71baa229dcbaa5d6459a5824145f7965d04e69a4
Parents: 52ad986
Author: Nikita Timofeev <stari...@gmail.com>
Authored: Mon Dec 18 17:17:47 2017 +0300
Committer: Nikita Timofeev <stari...@gmail.com>
Committed: Mon Dec 18 17:17:47 2017 +0300

----------------------------------------------------------------------
 docs/doc/src/main/resources/RELEASE-NOTES.txt   | 11 ++-
 .../apache/cayenne/access/trans/JoinStack.java  |  7 +-
 .../cayenne/CDOQualifiedEntitiesTest.java       | 82 +++++++++++++++++---
 .../cayenne/testdo/qualified/Qualified3.java    | 25 ++++++
 .../cayenne/testdo/qualified/Qualified4.java    | 25 ++++++
 .../testdo/qualified/auto/_Qualified3.java      | 40 ++++++++++
 .../testdo/qualified/auto/_Qualified4.java      | 54 +++++++++++++
 .../src/test/resources/qualified.map.xml        | 27 +++++++
 8 files changed, 254 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/71baa229/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 a8966e5..8b79d67 100644
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@ -8,10 +8,19 @@ To browse individual bug reports check out project issue 
tracker:
 https://issues.apache.org/jira/browse/CAY
 
 ----------------------------------
-Release: 3.1.2
+Release: 3.1.3
 Date: not yet released
 ----------------------------------
 
+Bug Fixes Since 3.1.2:
+
+CAY-2389 DbEntity qualifier with DbPath expression translates into wrong SQL
+
+----------------------------------
+Release: 3.1.2
+Date: 20 November 2017
+----------------------------------
+
 Bug Fixes Since 3.1.1:
 
 CAY-1969 Malformed EJBQL Yields NPE

http://git-wip-us.apache.org/repos/asf/cayenne/blob/71baa229/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/trans/JoinStack.java
----------------------------------------------------------------------
diff --git 
a/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/trans/JoinStack.java
 
b/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/trans/JoinStack.java
index 7f54603..77689cd 100644
--- 
a/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/trans/JoinStack.java
+++ 
b/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/trans/JoinStack.java
@@ -25,8 +25,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.exp.parser.ASTPath;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbJoin;
@@ -242,9 +241,9 @@ public class JoinStack {
         }
 
         public Object transform(Object input) {
-            if (input instanceof ASTObjPath) {
+            if (input instanceof ASTPath) {
                 return new ASTDbPath(pathToRoot.toString()
-                        + ((SimpleNode) input).getOperand(0));
+                        + ((ASTPath) input).getOperand(0));
             }
             return input;
         }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/71baa229/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/CDOQualifiedEntitiesTest.java
----------------------------------------------------------------------
diff --git 
a/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/CDOQualifiedEntitiesTest.java
 
b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/CDOQualifiedEntitiesTest.java
index 5d4ad69..41e2c37 100644
--- 
a/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/CDOQualifiedEntitiesTest.java
+++ 
b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/CDOQualifiedEntitiesTest.java
@@ -21,12 +21,18 @@ package org.apache.cayenne;
 import java.sql.Types;
 import java.util.List;
 
+import com.sun.org.apache.bcel.internal.generic.Select;
 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.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.ServerCase;
 import org.apache.cayenne.unit.di.server.UseServerRuntime;
@@ -45,6 +51,8 @@ public class CDOQualifiedEntitiesTest extends ServerCase {
 
     private TableHelper tQualified1;
     private TableHelper tQualified2;
+    private TableHelper tQualified3;
+    private TableHelper tQualified4;
 
     @Override
     protected void setUpAfterInjection() throws Exception {
@@ -53,18 +61,21 @@ public class CDOQualifiedEntitiesTest extends ServerCase {
 
         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 {
@@ -85,6 +96,17 @@ public class CDOQualifiedEntitiesTest extends ServerCase {
         tQualified2.insert(1, "OY1", null, 2);
     }
 
+    private void createJoinDataSet() throws Exception {
+        tQualified3.deleteAll();
+        tQualified4.deleteAll();
+
+        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);
+    }
+
     public void testReadToMany() throws Exception {
         if (accessStackAdapter.supportsNullBoolean()) {
 
@@ -123,4 +145,40 @@ public class CDOQualifiedEntitiesTest extends ServerCase {
             assertNull("" + target, target);
         }
     }
+
+    public void testJoinWithQualifier() throws Exception {
+        createJoinDataSet();
+
+        Expression qualifier = 
ExpressionFactory.likeExp(Qualified4.QUALIFIED3_PROPERTY + "."
+                + Qualified3.NAME_PROPERTY, "O%");
+        SelectQuery query = new SelectQuery(Qualified4.class, qualifier);
+        List<Qualified4> result = context.performQuery(query);
+
+        assertEquals(1, result.size());
+        assertEquals("SHOULD_SELECT", result.get(0).getName());
+    }
+
+    public void testJoinWithCustomDbQualifier() 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));
+
+            Expression qualifier = 
ExpressionFactory.likeExp(Qualified4.QUALIFIED3_PROPERTY + "."
+                    + Qualified3.NAME_PROPERTY, "O%");
+            SelectQuery query = new SelectQuery(Qualified4.class, qualifier);
+            List<Qualified4> result = context.performQuery(query);
+
+            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/71baa229/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/Qualified3.java
----------------------------------------------------------------------
diff --git 
a/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/Qualified3.java
 
b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/Qualified3.java
new file mode 100644
index 0000000..5f57d26
--- /dev/null
+++ 
b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/Qualified3.java
@@ -0,0 +1,25 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.testdo.qualified;
+
+import org.apache.cayenne.testdo.qualified.auto._Qualified3;
+
+public class Qualified3 extends _Qualified3 {
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/71baa229/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/Qualified4.java
----------------------------------------------------------------------
diff --git 
a/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/Qualified4.java
 
b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/Qualified4.java
new file mode 100644
index 0000000..f83a0ff
--- /dev/null
+++ 
b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/Qualified4.java
@@ -0,0 +1,25 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.testdo.qualified;
+
+import org.apache.cayenne.testdo.qualified.auto._Qualified4;
+
+public class Qualified4 extends _Qualified4 {
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/71baa229/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified3.java
----------------------------------------------------------------------
diff --git 
a/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified3.java
 
b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified3.java
new file mode 100644
index 0000000..0a6daa1
--- /dev/null
+++ 
b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified3.java
@@ -0,0 +1,40 @@
+package org.apache.cayenne.testdo.qualified.auto;
+
+import java.util.List;
+
+import org.apache.cayenne.CayenneDataObject;
+import org.apache.cayenne.testdo.qualified.Qualified4;
+
+/**
+ * Class _Qualified1 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 {
+
+    public static final String NAME_PROPERTY = "name";
+    public static final String QUALIFIED4S_PROPERTY = "qualified4s";
+
+    public static final String ID_PK_COLUMN = "ID";
+
+    public void setName(String name) {
+        writeProperty(NAME_PROPERTY, name);
+    }
+    public String getName() {
+        return (String)readProperty(NAME_PROPERTY);
+    }
+
+    public void addToQualified4s(Qualified4 obj) {
+        addToManyTarget(QUALIFIED4S_PROPERTY, obj, true);
+    }
+    public void removeFromQualified4s(Qualified4 obj) {
+        removeToManyTarget(QUALIFIED4S_PROPERTY, obj, true);
+    }
+    @SuppressWarnings("unchecked")
+    public List<Qualified4> getQualified2s() {
+        return (List<Qualified4>)readProperty(QUALIFIED4S_PROPERTY);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/71baa229/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified4.java
----------------------------------------------------------------------
diff --git 
a/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified4.java
 
b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified4.java
new file mode 100644
index 0000000..9915cec
--- /dev/null
+++ 
b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified4.java
@@ -0,0 +1,54 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.testdo.qualified.auto;
+
+import org.apache.cayenne.CayenneDataObject;
+import org.apache.cayenne.testdo.qualified.Qualified3;
+
+/**
+ * Class _Qualified2 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 {
+
+    public static final String NAME_PROPERTY = "name";
+    public static final String QUALIFIED3_PROPERTY = "qualified3";
+
+    public static final String ID_PK_COLUMN = "ID";
+
+    public void setName(String name) {
+        writeProperty(NAME_PROPERTY, name);
+    }
+    public String getName() {
+        return (String)readProperty(NAME_PROPERTY);
+    }
+
+    public void setQualified3(Qualified3 qualified3) {
+        setToOneTarget(QUALIFIED3_PROPERTY, qualified3, true);
+    }
+
+    public Qualified3 getQualified3() {
+        return (Qualified3)readProperty(QUALIFIED3_PROPERTY);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/71baa229/framework/cayenne-jdk1.5-unpublished/src/test/resources/qualified.map.xml
----------------------------------------------------------------------
diff --git 
a/framework/cayenne-jdk1.5-unpublished/src/test/resources/qualified.map.xml 
b/framework/cayenne-jdk1.5-unpublished/src/test/resources/qualified.map.xml
index 701c47d..e68cac0 100644
--- a/framework/cayenne-jdk1.5-unpublished/src/test/resources/qualified.map.xml
+++ b/framework/cayenne-jdk1.5-unpublished/src/test/resources/qualified.map.xml
@@ -15,6 +15,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"/>
@@ -25,12 +38,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>

Reply via email to