You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/12/13 14:39:14 UTC
cayenne git commit: CAY-2389 DbEntity qualifier with DbPath
expression translates into wrong SQL
Repository: cayenne
Updated Branches:
refs/heads/master 38f37d79a -> 41dd56c5a
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/41dd56c5
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/41dd56c5
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/41dd56c5
Branch: refs/heads/master
Commit: 41dd56c5af47c9d9afb8e259727dfaf4dd9a6cca
Parents: 38f37d7
Author: Nikita Timofeev <st...@gmail.com>
Authored: Wed Dec 13 17:12:01 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Wed Dec 13 17:12:01 2017 +0300
----------------------------------------------------------------------
.../access/translator/select/JoinStack.java | 7 +-
.../apache/cayenne/CDOQualifiedEntitiesIT.java | 81 +++++++++++---
.../cayenne/testdo/qualified/Qualified3.java | 9 ++
.../cayenne/testdo/qualified/Qualified4.java | 9 ++
.../testdo/qualified/auto/_Qualified3.java | 110 +++++++++++++++++++
.../testdo/qualified/auto/_Qualified4.java | 104 ++++++++++++++++++
.../src/test/resources/cayenne-qualified.xml | 2 +
.../src/test/resources/qualified.map.xml | 27 +++++
docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 +
9 files changed, 333 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/41dd56c5/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 937b818..11b57fc 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
@@ -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.DbEntity;
import org.apache.cayenne.map.DbJoin;
import org.apache.cayenne.map.DbRelationship;
@@ -211,8 +210,8 @@ public class JoinStack {
}
public Object apply(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/41dd56c5/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/41dd56c5/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/41dd56c5/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/41dd56c5/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..4a91a9f
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified3.java
@@ -0,0 +1,110 @@
+package org.apache.cayenne.testdo.qualified.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.List;
+
+import org.apache.cayenne.BaseDataObject;
+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 BaseDataObject {
+
+ 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);
+
+ protected String name;
+
+ protected Object qualified4s;
+
+ public void setName(String name) {
+ beforePropertyWrite("name", this.name, name);
+ this.name = name;
+ }
+
+ public String getName() {
+ beforePropertyRead("name");
+ return this.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");
+ }
+
+ @Override
+ public Object readPropertyDirectly(String propName) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch(propName) {
+ case "name":
+ return this.name;
+ case "qualified4s":
+ return this.qualified4s;
+ default:
+ return super.readPropertyDirectly(propName);
+ }
+ }
+
+ @Override
+ public void writePropertyDirectly(String propName, Object val) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (propName) {
+ case "name":
+ this.name = (String)val;
+ break;
+ case "qualified4s":
+ this.qualified4s = val;
+ break;
+ default:
+ super.writePropertyDirectly(propName, val);
+ }
+ }
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ writeSerialized(out);
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ readSerialized(in);
+ }
+
+ @Override
+ protected void writeState(ObjectOutputStream out) throws IOException {
+ super.writeState(out);
+ out.writeObject(this.name);
+ out.writeObject(this.qualified4s);
+ }
+
+ @Override
+ protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ super.readState(in);
+ this.name = (String)in.readObject();
+ this.qualified4s = in.readObject();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/41dd56c5/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..1c42281
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/testdo/qualified/auto/_Qualified4.java
@@ -0,0 +1,104 @@
+package org.apache.cayenne.testdo.qualified.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.cayenne.BaseDataObject;
+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 BaseDataObject {
+
+ 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);
+
+ protected String name;
+
+ protected Object qualified3;
+
+ public void setName(String name) {
+ beforePropertyWrite("name", this.name, name);
+ this.name = name;
+ }
+
+ public String getName() {
+ beforePropertyRead("name");
+ return this.name;
+ }
+
+ public void setQualified3(Qualified3 qualified3) {
+ setToOneTarget("qualified3", qualified3, true);
+ }
+
+ public Qualified3 getQualified3() {
+ return (Qualified3)readProperty("qualified3");
+ }
+
+ @Override
+ public Object readPropertyDirectly(String propName) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch(propName) {
+ case "name":
+ return this.name;
+ case "qualified3":
+ return this.qualified3;
+ default:
+ return super.readPropertyDirectly(propName);
+ }
+ }
+
+ @Override
+ public void writePropertyDirectly(String propName, Object val) {
+ if(propName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (propName) {
+ case "name":
+ this.name = (String)val;
+ break;
+ case "qualified3":
+ this.qualified3 = val;
+ break;
+ default:
+ super.writePropertyDirectly(propName, val);
+ }
+ }
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ writeSerialized(out);
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ readSerialized(in);
+ }
+
+ @Override
+ protected void writeState(ObjectOutputStream out) throws IOException {
+ super.writeState(out);
+ out.writeObject(this.name);
+ out.writeObject(this.qualified3);
+ }
+
+ @Override
+ protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ super.readState(in);
+ this.name = (String)in.readObject();
+ this.qualified3 = in.readObject();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/41dd56c5/cayenne-server/src/test/resources/cayenne-qualified.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/cayenne-qualified.xml b/cayenne-server/src/test/resources/cayenne-qualified.xml
index 2f67cd9..37805ab 100644
--- a/cayenne-server/src/test/resources/cayenne-qualified.xml
+++ b/cayenne-server/src/test/resources/cayenne-qualified.xml
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<domain xmlns="http://cayenne.apache.org/schema/10/domain"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://cayenne.apache.org/schema/10/domain http://cayenne.apache.org/schema/10/domain.xsd"
project-version="10">
<map name="qualified"/>
</domain>
http://git-wip-us.apache.org/repos/asf/cayenne/blob/41dd56c5/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 fb854cd..d75eb83 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">
<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">
+ <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/41dd56c5/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 4e002c4..7958307 100644
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@ -24,6 +24,7 @@ CAY-2381 cgen: meaningful PK with boxed type ends up with primitive type in gene
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.1.M1