HHH-15392 Infer Character as type for the LIKE predicate escape expression
This commit is contained in:
parent
02a1d1a27e
commit
38589b5e7b
|
@ -2181,7 +2181,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
return new SqmLikePredicate(
|
||||
(SqmExpression<?>) ctx.getChild( 0 ).accept( this ),
|
||||
(SqmExpression<?>) ctx.getChild( startIndex ).accept( this ),
|
||||
(SqmExpression<?>) ctx.getChild( startIndex + 1 ).getChild( 1 ).accept( this ),
|
||||
(SqmExpression<?>) ctx.getChild( startIndex + 1 ).accept( this ),
|
||||
negated,
|
||||
caseSensitive,
|
||||
creationContext.getNodeBuilder()
|
||||
|
@ -2198,6 +2198,38 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitLikeEscape(HqlParser.LikeEscapeContext ctx) {
|
||||
final ParseTree child = ctx.getChild( 1 );
|
||||
if ( child instanceof HqlParser.NamedParameterContext ) {
|
||||
return visitNamedParameter(
|
||||
(HqlParser.NamedParameterContext) child,
|
||||
creationContext.getNodeBuilder().getCharacterType()
|
||||
);
|
||||
}
|
||||
else if ( child instanceof HqlParser.PositionalParameterContext ) {
|
||||
return visitPositionalParameter(
|
||||
(HqlParser.PositionalParameterContext) child,
|
||||
creationContext.getNodeBuilder().getCharacterType()
|
||||
);
|
||||
}
|
||||
else {
|
||||
assert child instanceof TerminalNode;
|
||||
final TerminalNode terminalNode = (TerminalNode) child;
|
||||
final String escape = QuotingHelper.unquoteStringLiteral( terminalNode.getText() );
|
||||
if ( escape.length() != 1 ) {
|
||||
throw new SemanticException(
|
||||
"Escape character literals must have exactly a single character, but found: " + escape
|
||||
);
|
||||
}
|
||||
return new SqmLiteral<>(
|
||||
escape.charAt( 0 ),
|
||||
creationContext.getNodeBuilder().getCharacterType(),
|
||||
creationContext.getNodeBuilder()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPredicate visitMemberOfPredicate(HqlParser.MemberOfPredicateContext ctx) {
|
||||
final boolean negated = ctx.NOT() != null;
|
||||
|
@ -3398,10 +3430,17 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
|
||||
@Override
|
||||
public SqmNamedParameter<?> visitNamedParameter(HqlParser.NamedParameterContext ctx) {
|
||||
return visitNamedParameter( ctx, null );
|
||||
}
|
||||
|
||||
private <T> SqmNamedParameter<T> visitNamedParameter(
|
||||
HqlParser.NamedParameterContext ctx,
|
||||
SqmExpressible<T> expressibleType) {
|
||||
parameterStyle = parameterStyle.withNamed();
|
||||
final SqmNamedParameter<?> param = new SqmNamedParameter<>(
|
||||
final SqmNamedParameter<T> param = new SqmNamedParameter<>(
|
||||
ctx.getChild( 1 ).getText(),
|
||||
parameterDeclarationContextStack.getCurrent().isMultiValuedBindingAllowed(),
|
||||
expressibleType,
|
||||
creationContext.getNodeBuilder()
|
||||
);
|
||||
parameterCollector.addParameter( param );
|
||||
|
@ -3410,13 +3449,20 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
|
||||
@Override
|
||||
public SqmPositionalParameter<?> visitPositionalParameter(HqlParser.PositionalParameterContext ctx) {
|
||||
return visitPositionalParameter( ctx, null );
|
||||
}
|
||||
|
||||
private <T> SqmPositionalParameter<T> visitPositionalParameter(
|
||||
HqlParser.PositionalParameterContext ctx,
|
||||
SqmExpressible<T> expressibleType) {
|
||||
if ( ctx.getChildCount() == 1 ) {
|
||||
throw new SemanticException( "Unlabeled ordinal parameter ('?' rather than ?1)" );
|
||||
}
|
||||
parameterStyle = parameterStyle.withPositional();
|
||||
final SqmPositionalParameter<?> param = new SqmPositionalParameter<>(
|
||||
final SqmPositionalParameter<T> param = new SqmPositionalParameter<>(
|
||||
Integer.parseInt( ctx.getChild( 1 ).getText() ),
|
||||
parameterDeclarationContextStack.getCurrent().isMultiValuedBindingAllowed(),
|
||||
expressibleType,
|
||||
creationContext.getNodeBuilder()
|
||||
);
|
||||
parameterCollector.addParameter( param );
|
||||
|
|
|
@ -644,4 +644,6 @@ public interface NodeBuilder extends HibernateCriteriaBuilder {
|
|||
BasicType<Boolean> getBooleanType();
|
||||
|
||||
BasicType<Integer> getIntegerType();
|
||||
|
||||
BasicType<Character> getCharacterType();
|
||||
}
|
||||
|
|
|
@ -178,6 +178,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
private final transient ValueHandlingMode criteriaValueHandlingMode;
|
||||
private transient BasicType<Boolean> booleanType;
|
||||
private transient BasicType<Integer> integerType;
|
||||
private transient BasicType<Character> characterType;
|
||||
|
||||
public SqmCriteriaNodeBuilder(
|
||||
String uuid,
|
||||
|
@ -225,6 +226,15 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
return integerType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicType<Character> getCharacterType() {
|
||||
final BasicType<Character> characterType = this.characterType;
|
||||
if ( characterType == null ) {
|
||||
return this.characterType = getTypeConfiguration().getBasicTypeForJavaType( Character.class );
|
||||
}
|
||||
return characterType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceRegistry getServiceRegistry() {
|
||||
return serviceRegistry;
|
||||
|
|
|
@ -58,7 +58,7 @@ public class SqmLikePredicate extends AbstractNegatableSqmPredicate {
|
|||
matchExpression.applyInferableType( expressibleType );
|
||||
pattern.applyInferableType( expressibleType );
|
||||
if ( escapeCharacter != null ) {
|
||||
escapeCharacter.applyInferableType( expressibleType );
|
||||
escapeCharacter.applyInferableType( nodeBuilder.getCharacterType() );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ public class ILikeTest {
|
|||
scope.inTransaction(
|
||||
session -> {
|
||||
Query q = session.createQuery( "from BasicEntity be where be.data like 'Pr%$_%' escape :esc" )
|
||||
.setParameter("esc", "$");
|
||||
.setParameter("esc", '$');
|
||||
List l = q.getResultList();
|
||||
assertEquals( 2, l.size() );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue