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 2020/08/28 09:44:41 UTC
[cayenne] branch master updated: CAY-2671 QualifierTranslator fails
to translate expressions with compound PKs/FKs
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 62e7548 CAY-2671 QualifierTranslator fails to translate expressions with compound PKs/FKs
62e7548 is described below
commit 62e7548423b54e4e8e09a1f7eafcae1f28a52852
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Fri Aug 28 12:44:27 2020 +0300
CAY-2671 QualifierTranslator fails to translate expressions with compound PKs/FKs
---
RELEASE-NOTES.txt | 1 +
.../translator/select/QualifierTranslator.java | 25 +++++++-
.../translator/select/QualifierTranslatorIT.java | 66 ++++++++++++++++++++++
3 files changed, 90 insertions(+), 2 deletions(-)
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 72693b0..550fcf8 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -25,6 +25,7 @@ CAY-2670 CommitLog does not include FKs for deleted objects with one-way relatio
Bug Fixes:
CAY-2591 Modeler: project becomes dirty after click on dbImport or cgen tab
+CAY-2671 QualifierTranslator fails to translate expressions with compound PKs/FKs
----------------------------------
Release: 4.2.M1
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
index 494ae79..765b149 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
@@ -29,7 +29,15 @@ import org.apache.cayenne.access.sqlbuilder.sqltree.Node;
import org.apache.cayenne.access.sqlbuilder.sqltree.*;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.TraversalHandler;
-import org.apache.cayenne.exp.parser.*;
+import org.apache.cayenne.exp.parser.ASTCustomOperator;
+import org.apache.cayenne.exp.parser.ASTDbIdPath;
+import org.apache.cayenne.exp.parser.ASTDbPath;
+import org.apache.cayenne.exp.parser.ASTFullObject;
+import org.apache.cayenne.exp.parser.ASTFunctionCall;
+import org.apache.cayenne.exp.parser.ASTObjPath;
+import org.apache.cayenne.exp.parser.ASTSubquery;
+import org.apache.cayenne.exp.parser.PatternMatchNode;
+import org.apache.cayenne.exp.parser.SimpleNode;
import org.apache.cayenne.exp.property.Property;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
@@ -291,10 +299,23 @@ class QualifierTranslator implements TraversalHandler {
valueSnapshot = relationship.srcFkSnapshotWithTargetSnapshot(valueSnapshot);
}
+ // build compound PK/FK comparison node
+ Node multiValueComparison = buildMultiValueComparison(result, valueSnapshot);
+
+ // replace current node with multi value comparison
+ Node currentNodeParent = currentNode.getParent();
+ currentNodeParent.replaceChild(currentNodeParent.getChildrenCount() - 1, multiValueComparison);
+ multiValueComparison.setParent(currentNodeParent);
+ currentNode = currentNodeParent;
+
+ // we should skip all related nodes as we build this part of the tree manually
expressionsToSkip.add(node);
expressionsToSkip.add(parentNode);
+ for(int i=0; i<parentNode.getOperandCount(); i++) {
+ expressionsToSkip.add(parentNode.getOperand(i));
+ }
- return buildMultiValueComparison(result, valueSnapshot);
+ return null;
}
private Map<String, Object> getMultiAttributeValueSnapshot(Expression node, Expression parentNode) {
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java
new file mode 100644
index 0000000..9073e85
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java
@@ -0,0 +1,66 @@
+package org.apache.cayenne.access.translator.select;
+
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.access.sqlbuilder.SQLGenerationVisitor;
+import org.apache.cayenne.access.sqlbuilder.StringBuilderAppendable;
+import org.apache.cayenne.access.sqlbuilder.sqltree.Node;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.ObjectSelect;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.compound.CompoundFkTestEntity;
+import org.apache.cayenne.testdo.compound.CompoundPkTestEntity;
+import org.apache.cayenne.unit.UnitDbAdapter;
+import org.apache.cayenne.unit.di.server.CayenneProjects;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@UseServerRuntime(CayenneProjects.COMPOUND_PROJECT)
+public class QualifierTranslatorIT extends ServerCase {
+
+ @Inject
+ private ServerRuntime runtime;
+
+ @Inject
+ private ObjectContext context;
+
+ @Inject
+ protected DBHelper dbHelper;
+
+ @Before
+ public void setUp() throws Exception {
+ TableHelper tCompoundPKTest = new TableHelper(dbHelper, "COMPOUND_PK_TEST");
+ tCompoundPKTest.setColumns("KEY1", "KEY2", "NAME");
+ tCompoundPKTest.insert("PK1", "PK2", "BBB");
+ }
+
+ @Test
+ public void testCompoundPK() {
+ CompoundPkTestEntity testEntity = ObjectSelect.query(CompoundPkTestEntity.class).selectFirst(context);
+ assertNotNull(testEntity);
+
+ ObjectSelect<CompoundFkTestEntity> query = ObjectSelect.query(CompoundFkTestEntity.class)
+ .where(CompoundFkTestEntity.TO_COMPOUND_PK.eq(testEntity))
+ .and(CompoundFkTestEntity.NAME.like("test%"))
+ .and(CompoundFkTestEntity.NAME.contains("a"));
+
+ DefaultSelectTranslator translator
+ = new DefaultSelectTranslator(query, runtime.getDataDomain().getDefaultNode().getAdapter(), context.getEntityResolver());
+
+ QualifierTranslator qualifierTranslator = translator.getContext().getQualifierTranslator();
+
+ Node node = qualifierTranslator.translate(query.getWhere());
+
+ SQLGenerationVisitor visitor = new SQLGenerationVisitor(new StringBuilderAppendable());
+ node.visit(visitor);
+
+ assertEquals(" ( ( ( t0.F_KEY1 = 'PK1' ) AND ( t0.F_KEY2 = 'PK2' ) ) AND t0.NAME LIKE 'test%' ) AND t0.NAME LIKE '%a%'", visitor.getSQLString());
+ }
+
+}