HHH-16843 fix interpretation of 'value = null' in HQL
the previous implementation was not compliant with the JPA spec and defied logic
This commit is contained in:
parent
e15bee589f
commit
f77067b1b3
|
@ -2443,12 +2443,10 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
return ComparisonOperator.GREATER_THAN;
|
||||
case HqlLexer.GREATER_EQUAL:
|
||||
return ComparisonOperator.GREATER_THAN_OR_EQUAL;
|
||||
case HqlLexer.IS: {
|
||||
final TerminalNode secondToken = (TerminalNode) ctx.getChild( 1 );
|
||||
return secondToken.getSymbol().getType() == HqlLexer.NOT
|
||||
? ComparisonOperator.NOT_DISTINCT_FROM
|
||||
: ComparisonOperator.DISTINCT_FROM;
|
||||
}
|
||||
case HqlLexer.IS:
|
||||
return ctx.NOT() == null
|
||||
? ComparisonOperator.DISTINCT_FROM
|
||||
: ComparisonOperator.NOT_DISTINCT_FROM;
|
||||
default:
|
||||
throw new ParsingException("Unrecognized comparison operator");
|
||||
}
|
||||
|
@ -2456,11 +2454,11 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
|
||||
@Override
|
||||
public SqmPredicate visitComparisonPredicate(HqlParser.ComparisonPredicateContext ctx) {
|
||||
final ComparisonOperator comparisonOperator = (ComparisonOperator) ctx.getChild( 1 ).accept( this );
|
||||
final ComparisonOperator comparisonOperator = (ComparisonOperator) ctx.comparisonOperator().accept( this );
|
||||
final SqmExpression<?> left;
|
||||
final SqmExpression<?> right;
|
||||
final HqlParser.ExpressionContext leftExpressionContext = (HqlParser.ExpressionContext) ctx.getChild( 0 );
|
||||
final HqlParser.ExpressionContext rightExpressionContext = (HqlParser.ExpressionContext) ctx.getChild( 2 );
|
||||
final HqlParser.ExpressionContext leftExpressionContext = ctx.expression( 0 );
|
||||
final HqlParser.ExpressionContext rightExpressionContext = ctx.expression( 1 );
|
||||
switch (comparisonOperator) {
|
||||
case EQUAL:
|
||||
case NOT_EQUAL:
|
||||
|
@ -2499,24 +2497,6 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
left = l;
|
||||
right = r;
|
||||
}
|
||||
|
||||
// This is something that we used to support before 6 which is also used in our testsuite
|
||||
if ( left instanceof SqmLiteralNull<?> ) {
|
||||
return new SqmNullnessPredicate(
|
||||
right,
|
||||
comparisonOperator == ComparisonOperator.NOT_EQUAL
|
||||
|| comparisonOperator == ComparisonOperator.DISTINCT_FROM,
|
||||
creationContext.getNodeBuilder()
|
||||
);
|
||||
}
|
||||
else if ( right instanceof SqmLiteralNull<?> ) {
|
||||
return new SqmNullnessPredicate(
|
||||
left,
|
||||
comparisonOperator == ComparisonOperator.NOT_EQUAL
|
||||
|| comparisonOperator == ComparisonOperator.DISTINCT_FROM,
|
||||
creationContext.getNodeBuilder()
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
@ -2582,15 +2562,12 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
|
||||
@Override
|
||||
public SqmPredicate visitLikePredicate(HqlParser.LikePredicateContext ctx) {
|
||||
final boolean negated = ( (TerminalNode) ctx.getChild( 1 ) ).getSymbol().getType() == HqlParser.NOT;
|
||||
final int startIndex = negated ? 3 : 2;
|
||||
final boolean caseSensitive = ( (TerminalNode) ctx.getChild( negated ? 2 : 1 ) ).getSymbol()
|
||||
.getType() == HqlParser.LIKE;
|
||||
if ( ctx.getChildCount() == startIndex + 2 ) {
|
||||
final boolean negated = ctx.NOT() != null;
|
||||
final boolean caseSensitive = ctx.LIKE() != null;
|
||||
if ( ctx.likeEscape() == null ) {
|
||||
return new SqmLikePredicate(
|
||||
(SqmExpression<?>) ctx.getChild( 0 ).accept( this ),
|
||||
(SqmExpression<?>) ctx.getChild( startIndex ).accept( this ),
|
||||
(SqmExpression<?>) ctx.getChild( startIndex + 1 ).accept( this ),
|
||||
(SqmExpression<?>) ctx.expression(0).accept( this ),
|
||||
(SqmExpression<?>) ctx.expression(1).accept( this ),
|
||||
negated,
|
||||
caseSensitive,
|
||||
creationContext.getNodeBuilder()
|
||||
|
@ -2598,8 +2575,9 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
}
|
||||
else {
|
||||
return new SqmLikePredicate(
|
||||
(SqmExpression<?>) ctx.getChild( 0 ).accept( this ),
|
||||
(SqmExpression<?>) ctx.getChild( startIndex ).accept( this ),
|
||||
(SqmExpression<?>) ctx.expression(0).accept( this ),
|
||||
(SqmExpression<?>) ctx.expression(1).accept( this ),
|
||||
(SqmExpression<?>) ctx.likeEscape().accept( this ),
|
||||
negated,
|
||||
caseSensitive,
|
||||
creationContext.getNodeBuilder()
|
||||
|
|
|
@ -34,6 +34,7 @@ public class JavaTypeHelper {
|
|||
}
|
||||
|
||||
public static boolean isUnknown(JavaType<?> javaType) {
|
||||
return javaType.getClass() == UnknownBasicJavaType.class;
|
||||
return javaType == null
|
||||
|| javaType.getClass() == UnknownBasicJavaType.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.hibernate.internal.util.ReflectHelper;
|
|||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.sql.ast.spi.StringBuilderSqlAppender;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeHelper;
|
||||
import org.hibernate.type.descriptor.java.spi.UnknownBasicJavaType;
|
||||
import org.hibernate.type.format.FormatMapper;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.java.BasicPluralJavaType;
|
||||
|
|
|
@ -1158,7 +1158,7 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase {
|
|||
int count = s.createQuery( "update Mammal set bodyWeight = null" ).executeUpdate();
|
||||
assertEquals( "Incorrect deletion count on joined subclass", 2, count );
|
||||
|
||||
count = s.createQuery( "delete Animal where bodyWeight = null" ).executeUpdate();
|
||||
count = s.createQuery( "delete Animal where bodyWeight is null" ).executeUpdate();
|
||||
assertEquals( "Incorrect deletion count on joined subclass", 2, count );
|
||||
|
||||
t.commit();
|
||||
|
|
|
@ -47,13 +47,13 @@ public class DistinctSelectTest extends BaseCoreFunctionalTestCase {
|
|||
Transaction t = s.beginTransaction();
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
Tag tag = new Tag("Tag: " + UUID.randomUUID().toString());
|
||||
Tag tag = new Tag("Tag: " + UUID.randomUUID());
|
||||
tags.add(tag);
|
||||
s.save(tag);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM_OF_USERS; i++) {
|
||||
Entry e = new Entry("Entry: " + UUID.randomUUID().toString());
|
||||
Entry e = new Entry("Entry: " + UUID.randomUUID());
|
||||
e.getTags().addAll(tags);
|
||||
s.save(e);
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public class DistinctSelectTest extends BaseCoreFunctionalTestCase {
|
|||
|
||||
Session s = openSession();
|
||||
|
||||
List<Entry> entries = s.createQuery("select distinct e from Entry e join e.tags t where t.surrogate != null order by e.name").setFirstResult(10).setMaxResults(5).list();
|
||||
List<Entry> entries = s.createQuery("select distinct e from Entry e join e.tags t where t.surrogate is not null order by e.name").setFirstResult(10).setMaxResults(5).list();
|
||||
|
||||
// System.out.println(entries);
|
||||
Entry firstEntry = entries.remove(0);
|
||||
|
|
Loading…
Reference in New Issue