Author: stliu
Date: 2011-12-19 03:56:42 -0500 (Mon, 19 Dec 2011)
New Revision: 20999
Modified:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/hql/ast/HqlParser.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/hql/HqlParserTest.java
Log:
JBPAPP-6960 HHH-1780 Negation of EXISTS clause in HQL query does not work
Modified:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/hql/ast/HqlParser.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/hql/ast/HqlParser.java 2011-12-19
08:44:38 UTC (rev 20998)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/hql/ast/HqlParser.java 2011-12-19
08:56:42 UTC (rev 20999)
@@ -142,14 +142,14 @@
case OR:
x.setType(AND);
x.setText("{and}");
- negateNode( x.getFirstChild() );
- negateNode( x.getFirstChild().getNextSibling() );
+ x.setFirstChild( negateNode( x.getFirstChild() ) );
+ x.getFirstChild().setNextSibling( negateNode( x.getFirstChild().getNextSibling() )
);
return x;
case AND:
x.setType(OR);
x.setText("{or}");
- negateNode( x.getFirstChild() );
- negateNode( x.getFirstChild().getNextSibling() );
+ x.setFirstChild( negateNode( x.getFirstChild() ) );
+ x.getFirstChild().setNextSibling( negateNode( x.getFirstChild().getNextSibling() )
);
return x;
case EQ:
x.setType( NE );
@@ -212,7 +212,12 @@
return x.getFirstChild(); // (NOT (NOT x) ) => (x)
*/
default:
- return super.negateNode( x ); // Just add a 'not' parent.
+ AST not = super.negateNode( x ); // Just add a 'not' parent.
+ if ( not != x ){
+ not.setNextSibling( x.getNextSibling() );
+ x.setNextSibling( null );
+ }
+ return not;
}
}
Modified:
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/hql/HqlParserTest.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/hql/HqlParserTest.java 2011-12-19
08:44:38 UTC (rev 20998)
+++
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/hql/HqlParserTest.java 2011-12-19
08:56:42 UTC (rev 20999)
@@ -4,11 +4,13 @@
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
+import java.util.Stack;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
+import org.hibernate.hql.antlr.HqlTokenTypes;
import org.hibernate.hql.ast.HqlParser;
import org.hibernate.hql.ast.tree.Node;
import org.hibernate.hql.ast.util.ASTIterator;
@@ -212,6 +214,45 @@
+ "select name.nickName from eg.Name as name)" );
}
+ public void testHHH1780() throws Exception {
+ // verifies the tree contains a NOT->EXISTS subtree
+ class Verifier {
+ public boolean verify(AST root) {
+ Stack<AST> queue = new Stack<AST>();
+ queue.push( root );
+ while ( !queue.isEmpty() ) {
+ AST parent = queue.pop();
+ AST child = parent.getFirstChild();
+ while ( child != null ) {
+ if ( parent.getType() == HqlTokenTypes.NOT &&
+ child.getType() == HqlTokenTypes.EXISTS ) {
+ return true;
+ }
+ queue.push( child );
+ child = child.getNextSibling();
+ }
+ }
+ return false;
+ }
+ }
+
+ // test inversion of AND
+ AST ast = doParse(
+ "from Person p where not ( p.name is null and exists(select a.id from Address a
where a.id=p.id))",
+ false
+ );
+
+ assertTrue( new Verifier().verify( ast ) );
+
+ // test inversion of OR
+ ast = doParse(
+ "from Person p where not ( p.name is null or exists(select a.id from Address a
where a.id=p.id))",
+ false
+ );
+
+ assertTrue( new Verifier().verify( ast ) );
+ }
+
public void testDocoExamples912() throws Exception {
parse( "select ord.id, sum(price.amount), count(item)\n"
+ "from Order as ord join ord.lineItems as item\n"
Show replies by date