HHH-8901 replace "in ()" SQL with "in (null)" in QueryParameterBindingsImpl
This commit is contained in:
parent
4e449dfafa
commit
ab9ae43185
|
@ -46,13 +46,17 @@ public class InExpression implements Criterion {
|
|||
if ( columns.length > 1 ) {
|
||||
singleValueParam = '(' + singleValueParam + ')';
|
||||
}
|
||||
final String params = values.length > 0
|
||||
String params = values.length > 0
|
||||
? StringHelper.repeat( singleValueParam + ", ", values.length - 1 ) + singleValueParam
|
||||
: "";
|
||||
String cols = String.join( ", ", columns );
|
||||
if ( columns.length > 1 ) {
|
||||
cols = '(' + cols + ')';
|
||||
}
|
||||
// HHH-8901
|
||||
if ( ! criteriaQuery.getFactory().getDialect().supportsEmptyInList() && params.isEmpty() ) {
|
||||
params = "null";
|
||||
}
|
||||
return cols + " in (" + params + ')';
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -194,6 +194,10 @@ public class InPredicate<T>
|
|||
.append( ( (Renderable) value ).render( renderingContext ) );
|
||||
sep = ", ";
|
||||
}
|
||||
// HHH-8901
|
||||
if ( ! renderingContext.getDialect().supportsEmptyInList() && getValues().isEmpty() ) {
|
||||
buffer.append( "null" );
|
||||
}
|
||||
buffer.append( ')' );
|
||||
}
|
||||
return buffer.toString();
|
||||
|
|
|
@ -637,6 +637,11 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings {
|
|||
parameterBindingMap.put( syntheticParam, syntheticBinding );
|
||||
}
|
||||
|
||||
// HHH-8901
|
||||
if ( ! dialect.supportsEmptyInList() && expansionList.length() == 0 ) {
|
||||
expansionList.append( "null" );
|
||||
}
|
||||
|
||||
queryString = StringHelper.replace(
|
||||
beforePlaceholder,
|
||||
afterPlaceholder,
|
||||
|
|
|
@ -8,26 +8,22 @@ package org.hibernate.jpa.test.criteria.basic;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Path;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.hibernate.dialect.Oracle12cDialect;
|
||||
import org.hibernate.dialect.Oracle8iDialect;
|
||||
import org.hibernate.dialect.Oracle9Dialect;
|
||||
import org.hibernate.dialect.OracleDialect;
|
||||
import org.hibernate.jpa.test.metamodel.AbstractMetamodelSpecificTest;
|
||||
import org.hibernate.jpa.test.metamodel.CreditCard;
|
||||
import org.hibernate.jpa.test.metamodel.CreditCard_;
|
||||
import org.hibernate.jpa.test.metamodel.Customer_;
|
||||
import org.hibernate.jpa.test.metamodel.Order;
|
||||
import org.hibernate.jpa.test.metamodel.Order_;
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.junit.Before;
|
||||
|
@ -297,4 +293,21 @@ public class PredicateTest extends AbstractMetamodelSpecificTest {
|
|||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-8901" )
|
||||
@RequiresDialectFeature( DialectChecks.NotSupportsEmptyInListCheck.class )
|
||||
public void testEmptyInPredicate() {
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
CriteriaQuery<Order> orderCriteria = builder.createQuery( Order.class );
|
||||
Root<Order> orderRoot = orderCriteria.from( Order.class );
|
||||
orderCriteria.select( orderRoot );
|
||||
orderCriteria.where( builder.in( orderRoot.get("totalPrice") ) );
|
||||
|
||||
List<Order> orders = em.createQuery( orderCriteria ).getResultList();
|
||||
assertTrue( orders.isEmpty() );
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,15 @@ package org.hibernate.test.criteria;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -42,4 +46,24 @@ public class InTest extends BaseCoreFunctionalTestCase {
|
|||
tx.rollback();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-8901" )
|
||||
@RequiresDialectFeature(DialectChecks.NotSupportsEmptyInListCheck.class)
|
||||
public void testEmptyInListForDialectNotSupportsEmptyInList() {
|
||||
Session session = openSession();
|
||||
Transaction tx = session.beginTransaction();
|
||||
session.save( new Woman() );
|
||||
session.save( new Man() );
|
||||
session.flush();
|
||||
tx.commit();
|
||||
session.close();
|
||||
session = openSession();
|
||||
tx = session.beginTransaction();
|
||||
List persons = session.createCriteria( Person.class ).add(
|
||||
Restrictions.in( "name", Collections.emptySet() ) ).list();
|
||||
assertEquals( 0, persons.size() );
|
||||
tx.rollback();
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,18 @@
|
|||
*/
|
||||
package org.hibernate.test.hql;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hibernate.testing.junit4.ExtraAssertions.assertClassAssignability;
|
||||
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.Date;
|
||||
|
@ -13,11 +25,11 @@ import java.sql.Time;
|
|||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Query;
|
||||
|
@ -53,19 +65,6 @@ import org.hibernate.internal.util.StringHelper;
|
|||
import org.hibernate.loader.MultipleBagFetchException;
|
||||
import org.hibernate.persister.entity.DiscriminatorType;
|
||||
import org.hibernate.stat.QueryStatistics;
|
||||
import org.hibernate.transform.DistinctRootEntityResultTransformer;
|
||||
import org.hibernate.transform.Transformers;
|
||||
import org.hibernate.type.ComponentType;
|
||||
import org.hibernate.type.ManyToOneType;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.FailureExpected;
|
||||
import org.hibernate.testing.RequiresDialect;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.hibernate.test.any.IntegerPropertyValue;
|
||||
import org.hibernate.test.any.PropertySet;
|
||||
import org.hibernate.test.any.PropertyValue;
|
||||
|
@ -75,24 +74,20 @@ import org.hibernate.test.cid.LineItem;
|
|||
import org.hibernate.test.cid.LineItem.Id;
|
||||
import org.hibernate.test.cid.Order;
|
||||
import org.hibernate.test.cid.Product;
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.FailureExpected;
|
||||
import org.hibernate.testing.RequiresDialect;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.hibernate.transform.DistinctRootEntityResultTransformer;
|
||||
import org.hibernate.transform.Transformers;
|
||||
import org.hibernate.type.ComponentType;
|
||||
import org.hibernate.type.ManyToOneType;
|
||||
import org.hibernate.type.Type;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hibernate.testing.junit4.ExtraAssertions.assertClassAssignability;
|
||||
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.hibernate.testing.transaction.TransactionUtil2.inTransaction;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Tests the integration of the new AST parser into the loading of query results using
|
||||
* the Hibernate persisters and loaders.
|
||||
|
@ -663,6 +658,35 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
|
|||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-8901" )
|
||||
@RequiresDialectFeature(DialectChecks.NotSupportsEmptyInListCheck.class)
|
||||
public void testEmptyInListForDialectsNotSupportsEmptyInList() {
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
Human human = new Human();
|
||||
human.setName( new Name( "Lukasz", null, "Antoniak" ) );
|
||||
human.setNickName( "NONE" );
|
||||
session.save( human );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
|
||||
session = openSession();
|
||||
session.beginTransaction();
|
||||
List results = session.createQuery( "from Human h where h.nickName in (:nickNames)" )
|
||||
.setParameter("nickNames", Collections.emptySet() )
|
||||
.list();
|
||||
assertEquals( 0, results.size() );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
|
||||
session = openSession();
|
||||
session.beginTransaction();
|
||||
session.delete( human );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-2851")
|
||||
public void testMultipleRefsToSameParam() {
|
||||
|
@ -982,7 +1006,7 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
|
|||
else {
|
||||
s.createQuery( "from Animal where lower(upper('foo') || upper(:bar)) like 'f%'" ).setString( "bar", "xyz" ).list();
|
||||
}
|
||||
|
||||
|
||||
if ( getDialect() instanceof AbstractHANADialect ) {
|
||||
s.createQuery( "from Animal where abs(cast(1 as double) - cast(:param as double)) = 1.0" )
|
||||
.setLong( "param", 1 ).list();
|
||||
|
|
|
@ -55,6 +55,12 @@ abstract public class DialectChecks {
|
|||
}
|
||||
}
|
||||
|
||||
public static class NotSupportsEmptyInListCheck implements DialectCheck {
|
||||
public boolean isMatch(Dialect dialect) {
|
||||
return !dialect.supportsEmptyInList();
|
||||
}
|
||||
}
|
||||
|
||||
public static class CaseSensitiveCheck implements DialectCheck {
|
||||
public boolean isMatch(Dialect dialect) {
|
||||
return dialect.areStringComparisonsCaseInsensitive();
|
||||
|
|
Loading…
Reference in New Issue