From 894665481c4a1d112b37bf5bf7cb50868cd38bd5 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Thu, 18 Feb 2010 17:00:47 +0000 Subject: [PATCH] HHH-4583 - Incorrect handling of empty conjunction and disjunction git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18839 1b8cb986-b30d-0410-93ca-fae66ebed9b2 --- .../ejb/criteria/CriteriaBuilderImpl.java | 23 +++--- .../BooleanStaticAssertionPredicate.java | 81 +++++++++++++++++++ .../ejb/criteria/basic/ExpressionsTest.java | 60 ++++++++++++++ 3 files changed, 154 insertions(+), 10 deletions(-) create mode 100644 entitymanager/src/main/java/org/hibernate/ejb/criteria/predicate/BooleanStaticAssertionPredicate.java diff --git a/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaBuilderImpl.java b/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaBuilderImpl.java index 191a1fffec..9f29b3c863 100644 --- a/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaBuilderImpl.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaBuilderImpl.java @@ -73,6 +73,7 @@ import org.hibernate.ejb.criteria.path.PluralAttributePath; import org.hibernate.ejb.criteria.predicate.BooleanAssertionPredicate; import org.hibernate.ejb.criteria.predicate.BooleanExpressionPredicate; +import org.hibernate.ejb.criteria.predicate.BooleanStaticAssertionPredicate; import org.hibernate.ejb.criteria.predicate.NullnessPredicate; import org.hibernate.ejb.criteria.predicate.CompoundPredicate; import org.hibernate.ejb.criteria.predicate.ComparisonPredicate; @@ -316,9 +317,11 @@ public Predicate disjunction() { public Predicate isTrue(Expression expression) { if ( CompoundPredicate.class.isInstance( expression ) ) { final CompoundPredicate predicate = (CompoundPredicate) expression; - if ( predicate.getOperator() == Predicate.BooleanOperator.OR - && predicate.getExpressions().size() == 0 ) { - predicate.not(); + if ( predicate.getExpressions().size() == 0 ) { + return new BooleanStaticAssertionPredicate( + this, + predicate.getOperator() == Predicate.BooleanOperator.AND + ); } return predicate; } @@ -334,13 +337,13 @@ else if ( Predicate.class.isInstance( expression ) ) { public Predicate isFalse(Expression expression) { if ( CompoundPredicate.class.isInstance( expression ) ) { final CompoundPredicate predicate = (CompoundPredicate) expression; - if ( predicate.getOperator() == Predicate.BooleanOperator.OR - && predicate.getExpressions().size() == 0 ) { - // nothing to do - } - else { - predicate.not(); + if ( predicate.getExpressions().size() == 0 ) { + return new BooleanStaticAssertionPredicate( + this, + predicate.getOperator() == Predicate.BooleanOperator.OR + ); } + predicate.not(); return predicate; } else if ( Predicate.class.isInstance( expression ) ) { @@ -351,7 +354,7 @@ else if ( Predicate.class.isInstance( expression ) ) { return new BooleanAssertionPredicate( this, expression, Boolean.FALSE ); } - /** + /**s * {@inheritDoc} */ public Predicate isNull(Expression x) { diff --git a/entitymanager/src/main/java/org/hibernate/ejb/criteria/predicate/BooleanStaticAssertionPredicate.java b/entitymanager/src/main/java/org/hibernate/ejb/criteria/predicate/BooleanStaticAssertionPredicate.java new file mode 100644 index 0000000000..24ada02831 --- /dev/null +++ b/entitymanager/src/main/java/org/hibernate/ejb/criteria/predicate/BooleanStaticAssertionPredicate.java @@ -0,0 +1,81 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.ejb.criteria.predicate; + +import java.io.Serializable; + +import org.hibernate.ejb.criteria.CriteriaBuilderImpl; +import org.hibernate.ejb.criteria.CriteriaQueryCompiler; +import org.hibernate.ejb.criteria.ParameterRegistry; + +/** + * Predicate used to assert a static boolean condition. + * + * @author Steve Ebersole + */ +public class BooleanStaticAssertionPredicate + extends AbstractSimplePredicate + implements Serializable { + private final Boolean assertedValue; + + public BooleanStaticAssertionPredicate( + CriteriaBuilderImpl criteriaBuilder, + Boolean assertedValue) { + super( criteriaBuilder ); + this.assertedValue = assertedValue; + } + + public Boolean getAssertedValue() { + return assertedValue; + } + + /** + * {@inheritDoc} + */ + public void registerParameters(ParameterRegistry registry) { + // nada + } + + /** + * {@inheritDoc} + */ + public String render(CriteriaQueryCompiler.RenderingContext renderingContext) { + boolean isTrue = getAssertedValue(); + if ( isNegated() ) { + isTrue = !isTrue; + } + + return isTrue + ? "1=1" + : "0=1"; + } + + /** + * {@inheritDoc} + */ + public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) { + return render( renderingContext ); + } + +} \ No newline at end of file diff --git a/entitymanager/src/test/java/org/hibernate/ejb/criteria/basic/ExpressionsTest.java b/entitymanager/src/test/java/org/hibernate/ejb/criteria/basic/ExpressionsTest.java index 1e65eda44b..f3e82fbc7e 100644 --- a/entitymanager/src/test/java/org/hibernate/ejb/criteria/basic/ExpressionsTest.java +++ b/entitymanager/src/test/java/org/hibernate/ejb/criteria/basic/ExpressionsTest.java @@ -82,6 +82,66 @@ public void testEmptyConjunction() { em.close(); } + public void testEmptyConjunctionIsTrue() { + EntityManager em = getOrCreateEntityManager(); + em.getTransaction().begin(); + CriteriaQuery criteria = builder.createQuery( Product.class ); + criteria.from( Product.class ); + criteria.where( builder.isTrue( builder.and() ) ); + List result = em.createQuery( criteria ).getResultList(); + assertEquals( 1, result.size() ); + em.getTransaction().commit(); + em.close(); + } + + public void testEmptyConjunctionIsFalse() { + EntityManager em = getOrCreateEntityManager(); + em.getTransaction().begin(); + CriteriaQuery criteria = builder.createQuery( Product.class ); + criteria.from( Product.class ); + criteria.where( builder.isFalse( builder.and() ) ); + List result = em.createQuery( criteria ).getResultList(); + assertEquals( 0, result.size() ); + em.getTransaction().commit(); + em.close(); + } + + public void testEmptyDisjunction() { + EntityManager em = getOrCreateEntityManager(); + em.getTransaction().begin(); + CriteriaQuery criteria = builder.createQuery( Product.class ); + criteria.from( Product.class ); + criteria.where( builder.disjunction() ); + List result = em.createQuery( criteria ).getResultList(); + assertEquals( 0, result.size() ); + em.getTransaction().commit(); + em.close(); + } + + public void testEmptyDisjunctionIsTrue() { + EntityManager em = getOrCreateEntityManager(); + em.getTransaction().begin(); + CriteriaQuery criteria = builder.createQuery( Product.class ); + criteria.from( Product.class ); + criteria.where( builder.isTrue( builder.disjunction() ) ); + List result = em.createQuery( criteria ).getResultList(); + assertEquals( 0, result.size() ); + em.getTransaction().commit(); + em.close(); + } + + public void testEmptyDisjunctionIsFalse() { + EntityManager em = getOrCreateEntityManager(); + em.getTransaction().begin(); + CriteriaQuery criteria = builder.createQuery( Product.class ); + criteria.from( Product.class ); + criteria.where( builder.isFalse( builder.disjunction() ) ); + List result = em.createQuery( criteria ).getResultList(); + assertEquals( 1, result.size() ); + em.getTransaction().commit(); + em.close(); + } + public void testDiff() { EntityManager em = getOrCreateEntityManager(); em.getTransaction().begin();