HHH-17804 roll back change to semantics of 'null in ()'
It turns out that SQL databases (IMO wrongly) treat the expression 'null in (select 1 where false)' as false instead of null. And as of JPA 3.2, we're free to interpret 'null in ()' consistently with that, which we should do. So my change made things worse rather than better. Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
parent
15cbebbbf9
commit
de3a4c0af9
|
@ -3206,7 +3206,7 @@ public abstract class AbstractEntityPersister
|
||||||
Map<String, EntityNameUse> entityNameUses,
|
Map<String, EntityNameUse> entityNameUses,
|
||||||
MappingMetamodelImplementor mappingMetamodel,
|
MappingMetamodelImplementor mappingMetamodel,
|
||||||
String alias) {
|
String alias) {
|
||||||
final InFragment frag = new InFragment( false );
|
final InFragment frag = new InFragment();
|
||||||
if ( isDiscriminatorFormula() ) {
|
if ( isDiscriminatorFormula() ) {
|
||||||
frag.setFormula( alias, getDiscriminatorFormulaTemplate() );
|
frag.setFormula( alias, getDiscriminatorFormulaTemplate() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,15 +21,10 @@ import org.hibernate.internal.util.StringHelper;
|
||||||
@Internal
|
@Internal
|
||||||
public class InFragment {
|
public class InFragment {
|
||||||
|
|
||||||
public InFragment(boolean columnCanBeNull) {
|
|
||||||
this.columnCanBeNull = columnCanBeNull;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final String NULL = "null";
|
public static final String NULL = "null";
|
||||||
public static final String NOT_NULL = "not null";
|
public static final String NOT_NULL = "not null";
|
||||||
|
|
||||||
protected String columnName;
|
protected String columnName;
|
||||||
protected boolean columnCanBeNull;
|
|
||||||
protected List<Object> values = new ArrayList<>();
|
protected List<Object> values = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,15 +66,7 @@ public class InFragment {
|
||||||
|
|
||||||
switch ( values.size() ) {
|
switch ( values.size() ) {
|
||||||
case 0: {
|
case 0: {
|
||||||
if ( columnCanBeNull ) {
|
return "0=1";
|
||||||
return buf.append( "(1 = case when " )
|
|
||||||
.append( columnName )
|
|
||||||
.append(" is not null then 0 end)")
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return "0=1";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
Object value = values.get( 0 );
|
Object value = values.get( 0 );
|
||||||
|
|
|
@ -7641,7 +7641,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
public void visitInListPredicate(InListPredicate inListPredicate) {
|
public void visitInListPredicate(InListPredicate inListPredicate) {
|
||||||
final List<Expression> listExpressions = inListPredicate.getListExpressions();
|
final List<Expression> listExpressions = inListPredicate.getListExpressions();
|
||||||
if ( listExpressions.isEmpty() ) {
|
if ( listExpressions.isEmpty() ) {
|
||||||
emptyInList( inListPredicate );
|
appendSql( "1=" + ( inListPredicate.isNegated() ? "1" : "0" ) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Function<Expression, Expression> itemAccessor = Function.identity();
|
Function<Expression, Expression> itemAccessor = Function.identity();
|
||||||
|
@ -7748,16 +7748,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void emptyInList(InListPredicate inListPredicate) {
|
|
||||||
appendSql("(");
|
|
||||||
appendSql( inListPredicate.isNegated() ? "0" : "1" );
|
|
||||||
appendSql(" = case when ");
|
|
||||||
inListPredicate.getTestExpression().accept( this );
|
|
||||||
appendSql( " is not null then 0");
|
|
||||||
// dialect.appendBooleanValueString( this, inListPredicate.isNegated() );
|
|
||||||
appendSql(" end)");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void appendInClauseSeparator(InListPredicate inListPredicate) {
|
private void appendInClauseSeparator(InListPredicate inListPredicate) {
|
||||||
appendSql( CLOSE_PARENTHESIS );
|
appendSql( CLOSE_PARENTHESIS );
|
||||||
appendSql( inListPredicate.isNegated() ? " and " : " or " );
|
appendSql( inListPredicate.isNegated() ? " and " : " or " );
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -334,7 +335,7 @@ public class PredicateTest extends AbstractMetamodelSpecificTest {
|
||||||
CriteriaQuery<Order> orderCriteria = builder.createQuery( Order.class );
|
CriteriaQuery<Order> orderCriteria = builder.createQuery( Order.class );
|
||||||
Root<Order> orderRoot = orderCriteria.from( Order.class );
|
Root<Order> orderRoot = orderCriteria.from( Order.class );
|
||||||
orderCriteria.select( orderRoot );
|
orderCriteria.select( orderRoot );
|
||||||
orderCriteria.where( builder.in( orderRoot.get("creditCard") ) );
|
orderCriteria.where( builder.in( orderRoot.get("id") ) );
|
||||||
|
|
||||||
List<Order> orders = em.createQuery( orderCriteria ).getResultList();
|
List<Order> orders = em.createQuery( orderCriteria ).getResultList();
|
||||||
assertTrue( orders.isEmpty() );
|
assertTrue( orders.isEmpty() );
|
||||||
|
@ -350,10 +351,10 @@ public class PredicateTest extends AbstractMetamodelSpecificTest {
|
||||||
CriteriaQuery<Order> orderCriteria = builder.createQuery( Order.class );
|
CriteriaQuery<Order> orderCriteria = builder.createQuery( Order.class );
|
||||||
Root<Order> orderRoot = orderCriteria.from( Order.class );
|
Root<Order> orderRoot = orderCriteria.from( Order.class );
|
||||||
orderCriteria.select( orderRoot );
|
orderCriteria.select( orderRoot );
|
||||||
orderCriteria.where( builder.in( orderRoot.get("creditCard") ).not() );
|
orderCriteria.where( builder.in( orderRoot.get("id") ).not() );
|
||||||
|
|
||||||
List<Order> orders = em.createQuery( orderCriteria ).getResultList();
|
List<Order> orders = em.createQuery( orderCriteria ).getResultList();
|
||||||
assertTrue( orders.isEmpty() );
|
assertFalse( orders.isEmpty() );
|
||||||
em.getTransaction().commit();
|
em.getTransaction().commit();
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue