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>