CAY-2175 AliasName used in EJBQLQuery is not working if it contains mixed case
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/37faf1d3 Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/37faf1d3 Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/37faf1d3 Branch: refs/heads/STABLE-3.1 Commit: 37faf1d392bc5cc64d2bb3a2028241857938aedf Parents: e210860 Author: Nikita Timofeev <stari...@gmail.com> Authored: Fri Nov 10 15:44:52 2017 +0300 Committer: Nikita Timofeev <stari...@gmail.com> Committed: Fri Nov 10 15:44:52 2017 +0300 ---------------------------------------------------------------------- docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 + .../apache/cayenne/ejbql/parser/Compiler.java | 68 +++++++++++--------- .../ejbql/EJBQLCompiledExpressionTest.java | 32 +++++++++ 3 files changed, 69 insertions(+), 32 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/37faf1d3/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 19fd5a1..569ece0 100644 --- a/docs/doc/src/main/resources/RELEASE-NOTES.txt +++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt @@ -17,6 +17,7 @@ Bug Fixes Since 3.1.1: CAY-2084 ObjectIdQuery - no cache access polymorphism CAY-2101 DataContext.currentSnapshot() doesn't set snapshot entity name CAY-2137 When generating SQL from EJBQL, use "AND" to separate multiple join conditions +CAY-2175 AliasName used in EJBQLQuery is not working if it contains mixed case CAY-2226 PK generation for Frontbase: PK cache size must be ignored CAY-2276 PrePersist listener registered as PostPersist in LifecycleCallbackRegistry.addListener(Class<?>, LifecycleListener) http://git-wip-us.apache.org/repos/asf/cayenne/blob/37faf1d3/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java ---------------------------------------------------------------------- diff --git a/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java b/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java index ba8c9f6..30f8189 100644 --- a/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java +++ b/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java @@ -34,6 +34,7 @@ import org.apache.cayenne.ejbql.EJBQLExpressionVisitor; import org.apache.cayenne.map.DbAttribute; import org.apache.cayenne.map.DbJoin; import org.apache.cayenne.map.DbRelationship; +import org.apache.cayenne.map.Entity; import org.apache.cayenne.map.EntityResolver; import org.apache.cayenne.map.EntityResult; import org.apache.cayenne.map.ObjAttribute; @@ -87,49 +88,48 @@ class Compiler { Map<EJBQLPath, Integer> pathsInSelect = new HashMap<EJBQLPath, Integer>(); - if (parsed != null) { - for (int i = 0; i < parsed.getChildrenCount(); i++) { - if (parsed.getChild(i) instanceof EJBQLSelectClause) { + for (int i = 0; i < parsed.getChildrenCount(); i++) { + if (parsed.getChild(i) instanceof EJBQLSelectClause) { - EJBQLExpression parsedTemp = parsed.getChild(i); - boolean stop = false; + EJBQLExpression parsedTemp = parsed.getChild(i); + boolean stop = false; - while (parsedTemp.getChildrenCount() > 0 && !stop) { - EJBQLExpression newParsedTemp = null; - for (int j = 0; j < parsedTemp.getChildrenCount(); j++) { - if (parsedTemp.getChild(j) instanceof EJBQLSelectExpression) { - for (int k = 0; k < parsedTemp - .getChild(j) - .getChildrenCount(); k++) { + while (parsedTemp.getChildrenCount() > 0 && !stop) { + EJBQLExpression newParsedTemp = null; + for (int j = 0; j < parsedTemp.getChildrenCount(); j++) { + if (parsedTemp.getChild(j) instanceof EJBQLSelectExpression) { + for (int k = 0; k < parsedTemp + .getChild(j) + .getChildrenCount(); k++) { - if (parsedTemp.getChild(j).getChild(k) instanceof EJBQLPath) { - pathsInSelect.put((EJBQLPath) parsedTemp - .getChild(j) - .getChild(k), j); + if (parsedTemp.getChild(j).getChild(k) instanceof EJBQLPath) { + pathsInSelect.put((EJBQLPath) parsedTemp + .getChild(j) + .getChild(k), j); - } } } + } + else { + if (parsedTemp.getChild(j).getChildrenCount() == 0) { + stop = true; + } else { - if (parsedTemp.getChild(j).getChildrenCount() == 0) { - stop = true; - } - else { - newParsedTemp = parsedTemp.getChild(j); - } + newParsedTemp = parsedTemp.getChild(j); } } + } - if (!stop && newParsedTemp != null) { - parsedTemp = newParsedTemp; - } - else { - stop = true; - } + if (!stop && newParsedTemp != null) { + parsedTemp = newParsedTemp; + } + else { + stop = true; } } } } + // postprocess paths, now that all id vars are resolved if (paths != null) { for (EJBQLPath path : paths) { @@ -147,6 +147,10 @@ class Compiler { for (int i = 1; i < path.getChildrenCount(); i++) { String pathChunk = path.getChild(i).getText(); + if(pathChunk.endsWith(Entity.OUTER_JOIN_INDICATOR)) { + pathChunk = pathChunk.substring(0, pathChunk.length() - 1); + } + buffer.append('.').append(pathChunk); Property property = descriptor.getProperty(pathChunk); @@ -173,7 +177,7 @@ class Compiler { Integer integer = pathsInSelect.get(path); if (integer != null) { resultComponents.remove(integer.intValue()); - resultComponents.add(pathsInSelect.get(path).intValue(), ident); + resultComponents.add(integer, ident); rootId = pathRelationshipString; } } @@ -530,7 +534,7 @@ class Compiler { @Override public boolean visitPath(EJBQLExpression expression, int finishedChildIndex) { if (finishedChildIndex + 1 < expression.getChildrenCount()) { - this.id = ((EJBQLPath) expression).getId(); + this.id = normalizeIdPath(((EJBQLPath) expression).getId()); this.descriptor = descriptorsById.get(id); if (descriptor == null) { @@ -560,7 +564,7 @@ class Compiler { public boolean visitIdentifier(EJBQLExpression expression) { if (incoming != null) { - String aliasId = expression.getText(); + String aliasId = expression.getText().toLowerCase(); // map id variable to class descriptor ClassDescriptor old = descriptorsById.put(aliasId, descriptor); http://git-wip-us.apache.org/repos/asf/cayenne/blob/37faf1d3/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/ejbql/EJBQLCompiledExpressionTest.java ---------------------------------------------------------------------- diff --git a/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/ejbql/EJBQLCompiledExpressionTest.java b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/ejbql/EJBQLCompiledExpressionTest.java index 5e16edb..82f6392 100644 --- a/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/ejbql/EJBQLCompiledExpressionTest.java +++ b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/ejbql/EJBQLCompiledExpressionTest.java @@ -21,6 +21,7 @@ package org.apache.cayenne.ejbql; import org.apache.cayenne.configuration.server.ServerRuntime; import org.apache.cayenne.di.Inject; import org.apache.cayenne.map.EntityResolver; +import org.apache.cayenne.query.EJBQLQuery; import org.apache.cayenne.unit.di.server.ServerCase; import org.apache.cayenne.unit.di.server.UseServerRuntime; @@ -108,4 +109,35 @@ public class EJBQLCompiledExpressionTest extends ServerCase { assertNotNull(select3.getEntityDescriptor("a")); assertNotNull(select3.getEntityDescriptor("A")); } + + /** + * CAY-2175 + */ + public void testGetEntityDescriptorCaseSensitivityInJoin() { + EntityResolver resolver = runtime.getDataDomain().getEntityResolver(); + EJBQLParser parser = EJBQLParserFactory.getParser(); + + EJBQLCompiledExpression select1 = parser.compile( + "SELECT artistAlias FROM Artist artistAlias " + + "WHERE artistAlias.artistName = 'Abcd'", + resolver + ); + assertNotNull(select1.getEntityDescriptor("artistalias")); + assertNotNull(select1.getEntityDescriptor("artistAlias")); + assertNotNull(select1.getEntityDescriptor("ArTiStAlIaS")); + + EJBQLCompiledExpression select2 = parser.compile( + "SELECT artistalias from Artist AS ArtistAlias JOIN artistalias.paintingArray as PaintingAlias " + + "where aRtistALiaS.artistName = 'Abcd'", + resolver + ); + assertNotNull(select2.getEntityDescriptor("artistalias")); + assertNotNull(select2.getEntityDescriptor("artistAlias")); + assertNotNull(select2.getEntityDescriptor("ArTiStAlIaS")); + + assertNotNull(select2.getEntityDescriptor("PaintingAlias")); + assertNotNull(select2.getEntityDescriptor("paintingalias")); + assertNotNull(select2.getEntityDescriptor("PaInTinGAlIaS")); + } + }