You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by an...@apache.org on 2010/01/24 13:26:55 UTC
svn commit: r902551 - in /cayenne/main/trunk: docs/doc/src/main/resources/
framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/
framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/
framework/...
Author: andrey
Date: Sun Jan 24 12:26:55 2010
New Revision: 902551
URL: http://svn.apache.org/viewvc?rev=902551&view=rev
Log:
CAY-1371 EJBQL query doesn't preserve grouping by brackets
Added:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/AggregateConditionNode.java
Modified:
cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLAnd.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLNot.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLOr.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/EJBQLQueryTest.java
Modified: cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt?rev=902551&r1=902550&r2=902551&view=diff
==============================================================================
--- cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt (original)
+++ cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt Sun Jan 24 12:26:55 2010
@@ -59,6 +59,7 @@
CAY-1365 "= NULL" being used instead of "IS NULL" on an EJBQL expression..
CAY-1368 Left Join and Prefetches do not work together
CAY-1369 EJBQL: Fix likeIgnoreCase issues
+CAY-1371 EJBQL query doesn't preserve grouping by brackets
----------------------------------
Release: 3.0 RC 1
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java?rev=902551&r1=902550&r2=902551&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java Sun Jan 24 12:26:55 2010
@@ -31,6 +31,7 @@
import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
import org.apache.cayenne.ejbql.EJBQLException;
import org.apache.cayenne.ejbql.EJBQLExpression;
+import org.apache.cayenne.ejbql.parser.AggregateConditionNode;
import org.apache.cayenne.ejbql.parser.EJBQLDecimalLiteral;
import org.apache.cayenne.ejbql.parser.EJBQLEquals;
import org.apache.cayenne.ejbql.parser.EJBQLIdentificationVariable;
@@ -80,7 +81,7 @@
@Override
public boolean visitAnd(EJBQLExpression expression, int finishedChildIndex) {
- afterChild(expression, " AND", finishedChildIndex);
+ visitConditional((AggregateConditionNode) expression, " AND", finishedChildIndex);
return true;
}
@@ -380,7 +381,7 @@
@Override
public boolean visitOr(EJBQLExpression expression, int finishedChildIndex) {
- afterChild(expression, " OR", finishedChildIndex);
+ visitConditional((AggregateConditionNode) expression, " OR", finishedChildIndex);
return true;
}
@@ -572,6 +573,29 @@
return true;
}
+
+ /**
+ * Visits conditional node, suppling brackets if needed
+ */
+ void visitConditional(AggregateConditionNode e, String afterText, int childIndex) {
+ if (childIndex == -1 && needBracket(e)) {
+ context.append(" (");
+ }
+
+ afterChild(e, afterText, childIndex);
+
+ if (childIndex == e.getChildrenCount() - 1 && needBracket(e)) {
+ context.append(")");
+ }
+ }
+
+ /**
+ * Checks whether expression needs to be rounded by brackets
+ */
+ boolean needBracket(AggregateConditionNode e) {
+ return (e.jjtGetParent() instanceof AggregateConditionNode) &&
+ e.getPriority() > ((AggregateConditionNode) e.jjtGetParent()).getPriority();
+ }
protected void afterChild(EJBQLExpression e, String text, int childIndex) {
if (childIndex >= 0) {
Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/AggregateConditionNode.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/AggregateConditionNode.java?rev=902551&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/AggregateConditionNode.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/AggregateConditionNode.java Sun Jan 24 12:26:55 2010
@@ -0,0 +1,42 @@
+/*****************************************************************
+ * 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.ejbql.parser;
+
+/**
+ * Superclass of aggregated conditional nodes such as NOT, AND, OR.
+ * Defines priority of operations, so that SQL can be supplied with brackets as needed
+ *
+ * @since 3.0
+ */
+public abstract class AggregateConditionNode extends SimpleNode {
+ //defining all priorities here so that it would be easy to compare them visually
+ static final int NOT_PRIORITY = 10;
+ static final int AND_PRIORITY = 20;
+ static final int OR_PRIORITY = 30;
+
+ public AggregateConditionNode(int id) {
+ super(id);
+ }
+
+ /**
+ * Returns priority of conditional operator.
+ * This is used to decide whether brackets are needed in resulting SQL
+ */
+ public abstract int getPriority();
+}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLAnd.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLAnd.java?rev=902551&r1=902550&r2=902551&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLAnd.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLAnd.java Sun Jan 24 12:26:55 2010
@@ -23,7 +23,7 @@
/**
* @since 3.0
*/
-public class EJBQLAnd extends SimpleNode {
+public class EJBQLAnd extends AggregateConditionNode {
public EJBQLAnd(int id) {
super(id);
@@ -39,4 +39,9 @@
return super.visitChild(visitor, childIndex)
&& visitor.visitAnd(this, childIndex);
}
+
+ @Override
+ public int getPriority() {
+ return AND_PRIORITY;
+ }
}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLNot.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLNot.java?rev=902551&r1=902550&r2=902551&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLNot.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLNot.java Sun Jan 24 12:26:55 2010
@@ -23,7 +23,7 @@
/**
* @since 3.0
*/
-public class EJBQLNot extends SimpleNode {
+public class EJBQLNot extends AggregateConditionNode {
public EJBQLNot(int id) {
super(id);
@@ -33,4 +33,9 @@
protected boolean visitNode(EJBQLExpressionVisitor visitor) {
return visitor.visitNot(this);
}
+
+ @Override
+ public int getPriority() {
+ return NOT_PRIORITY;
+ }
}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLOr.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLOr.java?rev=902551&r1=902550&r2=902551&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLOr.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLOr.java Sun Jan 24 12:26:55 2010
@@ -23,7 +23,7 @@
/**
* @since 3.0
*/
-public class EJBQLOr extends SimpleNode {
+public class EJBQLOr extends AggregateConditionNode {
public EJBQLOr(int id) {
super(id);
@@ -38,4 +38,9 @@
protected boolean visitChild(EJBQLExpressionVisitor visitor, int childIndex) {
return super.visitChild(visitor, childIndex) && visitor.visitOr(this, childIndex);
}
+
+ @Override
+ public int getPriority() {
+ return OR_PRIORITY;
+ }
}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/EJBQLQueryTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/EJBQLQueryTest.java?rev=902551&r1=902550&r2=902551&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/EJBQLQueryTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/EJBQLQueryTest.java Sun Jan 24 12:26:55 2010
@@ -339,4 +339,39 @@
context.performQuery(query);
}
+
+ public void testOrBrackets() throws Exception {
+ deleteTestData();
+ ObjectContext context = createDataContext();
+
+ Artist a = context.newObject(Artist.class);
+ a.setArtistName("testOrBrackets");
+ context.commitChanges();
+
+ //this query is equivalent to (false and (false or true)) and
+ //should always return 0 rows
+ EJBQLQuery query = new EJBQLQuery("select a from Artist a " +
+ "where a.artistName <> a.artistName and " +
+ "(a.artistName <> a.artistName or a.artistName = a.artistName)");
+ assertEquals(context.performQuery(query).size(), 0);
+
+ //on the other hand, the following is equivalent to (false and false) or true) and
+ //should return >0 rows
+ query = new EJBQLQuery("select a from Artist a " +
+ "where a.artistName <> a.artistName and " +
+ "a.artistName <> a.artistName or a.artistName = a.artistName");
+ assertTrue(context.performQuery(query).size() > 0);
+
+ //checking brackets around not
+ query = new EJBQLQuery("select a from Artist a " +
+ "where not(a.artistName <> a.artistName and " +
+ "a.artistName <> a.artistName or a.artistName = a.artistName)");
+ assertEquals(context.performQuery(query).size(), 0);
+
+ //not is first to process
+ query = new EJBQLQuery("select a from Artist a " +
+ "where not a.artistName <> a.artistName or " +
+ "a.artistName = a.artistName");
+ assertTrue(context.performQuery(query).size() > 0);
+ }
}