|
32 | 32 | import java.util.Set; |
33 | 33 |
|
34 | 34 | import jakarta.persistence.criteria.Nulls; |
| 35 | +import org.antlr.v4.runtime.Token; |
35 | 36 | import org.hibernate.AssertionFailure; |
36 | 37 | import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; |
37 | 38 | import org.hibernate.cfg.QuerySettings; |
@@ -2460,6 +2461,91 @@ public SqmPredicate visitUnaryIsPredicate(HqlParser.UnaryIsPredicateContext ctx) |
2460 | 2461 | }; |
2461 | 2462 | } |
2462 | 2463 |
|
| 2464 | + @Override |
| 2465 | + public SqmPredicate visitBinaryExpressionPredicate(HqlParser.BinaryExpressionPredicateContext ctx) { |
| 2466 | + final var firstSymbol = ((TerminalNode) ctx.getChild( 1 )).getSymbol(); |
| 2467 | + final boolean negated; |
| 2468 | + final Token operationSymbol; |
| 2469 | + if ( firstSymbol.getType() == HqlParser.NOT ) { |
| 2470 | + negated = true; |
| 2471 | + operationSymbol = ((TerminalNode) ctx.getChild( 2 )).getSymbol(); |
| 2472 | + } |
| 2473 | + else { |
| 2474 | + negated = false; |
| 2475 | + operationSymbol = firstSymbol; |
| 2476 | + } |
| 2477 | + final var expressions = ctx.expression(); |
| 2478 | + final var lhsCtx = expressions.get( 0 ); |
| 2479 | + final var rhsCtx = expressions.get( 1 ); |
| 2480 | + return switch ( operationSymbol.getType() ) { |
| 2481 | + case HqlParser.CONTAINS -> { |
| 2482 | + final var lhs = (SqmExpression<?>) lhsCtx.accept( this ); |
| 2483 | + final var rhs = (SqmExpression<?>) rhsCtx.accept( this ); |
| 2484 | + final var lhsExpressible = lhs.getExpressible(); |
| 2485 | + if ( lhsExpressible != null && !(lhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
| 2486 | + throw new SemanticException( |
| 2487 | + "First operand for contains predicate must be a basic plural type expression, but found: " + lhsExpressible.getSqmType(), |
| 2488 | + query |
| 2489 | + ); |
| 2490 | + } |
| 2491 | + final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( |
| 2492 | + "array_contains" ).generateSqmExpression( |
| 2493 | + asList( lhs, rhs ), |
| 2494 | + null, |
| 2495 | + queryEngine() |
| 2496 | + ); |
| 2497 | + yield new SqmBooleanExpressionPredicate( contains, negated, nodeBuilder() ); |
| 2498 | + } |
| 2499 | + case HqlParser.INCLUDES -> { |
| 2500 | + final var lhs = (SqmExpression<?>) lhsCtx.accept( this ); |
| 2501 | + final var rhs = (SqmExpression<?>) rhsCtx.accept( this ); |
| 2502 | + final var lhsExpressible = lhs.getExpressible(); |
| 2503 | + final var rhsExpressible = rhs.getExpressible(); |
| 2504 | + if ( lhsExpressible != null && !( lhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
| 2505 | + throw new SemanticException( |
| 2506 | + "First operand for includes predicate must be a basic plural type expression, but found: " |
| 2507 | + + lhsExpressible.getSqmType(), |
| 2508 | + query |
| 2509 | + ); |
| 2510 | + } |
| 2511 | + if ( rhsExpressible != null && !( rhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
| 2512 | + throw new SemanticException( |
| 2513 | + "Second operand for includes predicate must be a basic plural type expression, but found: " |
| 2514 | + + rhsExpressible.getSqmType(), |
| 2515 | + query |
| 2516 | + ); |
| 2517 | + } |
| 2518 | + final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( "array_includes" ).generateSqmExpression( |
| 2519 | + asList( lhs, rhs ), |
| 2520 | + null, |
| 2521 | + queryEngine() |
| 2522 | + ); |
| 2523 | + yield new SqmBooleanExpressionPredicate( contains, negated, nodeBuilder() ); |
| 2524 | + } |
| 2525 | + case HqlParser.INTERSECTS -> { |
| 2526 | + final var lhs = (SqmExpression<?>) lhsCtx.accept( this ); |
| 2527 | + final var rhs = (SqmExpression<?>) rhsCtx.accept( this ); |
| 2528 | + final var lhsExpressible = lhs.getExpressible(); |
| 2529 | + if ( lhsExpressible != null && !( lhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
| 2530 | + throw new SemanticException( |
| 2531 | + "First operand for intersects predicate must be a basic plural type expression, but found: " |
| 2532 | + + lhsExpressible.getSqmType(), |
| 2533 | + query |
| 2534 | + ); |
| 2535 | + } |
| 2536 | + final SelfRenderingSqmFunction<Boolean> contains = |
| 2537 | + getFunctionDescriptor( "array_intersects" ) |
| 2538 | + .generateSqmExpression( |
| 2539 | + asList( lhs, rhs ), |
| 2540 | + null, |
| 2541 | + queryEngine() |
| 2542 | + ); |
| 2543 | + yield new SqmBooleanExpressionPredicate( contains, negated, nodeBuilder() ); |
| 2544 | + } |
| 2545 | + default -> throw new AssertionError( "Unknown binary expression predicate: " + operationSymbol ); |
| 2546 | + }; |
| 2547 | + } |
| 2548 | + |
2463 | 2549 | @Override |
2464 | 2550 | public Object visitComparisonOperator(HqlParser.ComparisonOperatorContext ctx) { |
2465 | 2551 | final TerminalNode firstToken = (TerminalNode) ctx.getChild( 0 ); |
@@ -2614,26 +2700,6 @@ private String getPossibleEnumValue(HqlParser.ExpressionContext expressionContex |
2614 | 2700 | return null; |
2615 | 2701 | } |
2616 | 2702 |
|
2617 | | - @Override |
2618 | | - public SqmPredicate visitContainsPredicate(HqlParser.ContainsPredicateContext ctx) { |
2619 | | - final boolean negated = ctx.NOT() != null; |
2620 | | - final SqmExpression<?> lhs = (SqmExpression<?>) ctx.expression( 0 ).accept( this ); |
2621 | | - final SqmExpression<?> rhs = (SqmExpression<?>) ctx.expression( 1 ).accept( this ); |
2622 | | - final SqmExpressible<?> lhsExpressible = lhs.getExpressible(); |
2623 | | - if ( lhsExpressible != null && !( lhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
2624 | | - throw new SemanticException( |
2625 | | - "First operand for contains predicate must be a basic plural type expression, but found: " + lhsExpressible.getSqmType(), |
2626 | | - query |
2627 | | - ); |
2628 | | - } |
2629 | | - final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( "array_contains" ).generateSqmExpression( |
2630 | | - asList( lhs, rhs ), |
2631 | | - null, |
2632 | | - queryEngine() |
2633 | | - ); |
2634 | | - return new SqmBooleanExpressionPredicate( contains, negated, nodeBuilder() ); |
2635 | | - } |
2636 | | - |
2637 | 2703 | @Override |
2638 | 2704 | public SqmExpression<?> visitJsonValueFunction(HqlParser.JsonValueFunctionContext ctx) { |
2639 | 2705 | checkJsonFunctionsEnabled( ctx ); |
@@ -3168,56 +3234,6 @@ private void checkXmlFunctionsEnabled(ParserRuleContext ctx) { |
3168 | 3234 | } |
3169 | 3235 | } |
3170 | 3236 |
|
3171 | | - @Override |
3172 | | - public SqmPredicate visitIncludesPredicate(HqlParser.IncludesPredicateContext ctx) { |
3173 | | - final boolean negated = ctx.NOT() != null; |
3174 | | - final SqmExpression<?> lhs = (SqmExpression<?>) ctx.expression( 0 ).accept( this ); |
3175 | | - final SqmExpression<?> rhs = (SqmExpression<?>) ctx.expression( 1 ).accept( this ); |
3176 | | - final SqmExpressible<?> lhsExpressible = lhs.getExpressible(); |
3177 | | - final SqmExpressible<?> rhsExpressible = rhs.getExpressible(); |
3178 | | - if ( lhsExpressible != null && !( lhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
3179 | | - throw new SemanticException( |
3180 | | - "First operand for includes predicate must be a basic plural type expression, but found: " |
3181 | | - + lhsExpressible.getSqmType(), |
3182 | | - query |
3183 | | - ); |
3184 | | - } |
3185 | | - if ( rhsExpressible != null && !( rhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
3186 | | - throw new SemanticException( |
3187 | | - "Second operand for includes predicate must be a basic plural type expression, but found: " |
3188 | | - + rhsExpressible.getSqmType(), |
3189 | | - query |
3190 | | - ); |
3191 | | - } |
3192 | | - final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( "array_includes" ).generateSqmExpression( |
3193 | | - asList( lhs, rhs ), |
3194 | | - null, |
3195 | | - queryEngine() |
3196 | | - ); |
3197 | | - return new SqmBooleanExpressionPredicate( contains, negated, nodeBuilder() ); |
3198 | | - } |
3199 | | - |
3200 | | - @Override |
3201 | | - public SqmPredicate visitIntersectsPredicate(HqlParser.IntersectsPredicateContext ctx) { |
3202 | | - final boolean negated = ctx.NOT() != null; |
3203 | | - final SqmExpression<?> lhs = (SqmExpression<?>) ctx.expression( 0 ).accept( this ); |
3204 | | - final SqmExpression<?> rhs = (SqmExpression<?>) ctx.expression( 1 ).accept( this ); |
3205 | | - final SqmExpressible<?> lhsExpressible = lhs.getExpressible(); |
3206 | | - if ( lhsExpressible != null && !( lhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
3207 | | - throw new SemanticException( |
3208 | | - "First operand for intersects predicate must be a basic plural type expression, but found: " |
3209 | | - + lhsExpressible.getSqmType(), |
3210 | | - query |
3211 | | - ); |
3212 | | - } |
3213 | | - final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( "array_intersects" ).generateSqmExpression( |
3214 | | - asList( lhs, rhs ), |
3215 | | - null, |
3216 | | - queryEngine() |
3217 | | - ); |
3218 | | - return new SqmBooleanExpressionPredicate( contains, negated, nodeBuilder() ); |
3219 | | - } |
3220 | | - |
3221 | 3237 | @Override |
3222 | 3238 | public SqmPredicate visitLikePredicate(HqlParser.LikePredicateContext ctx) { |
3223 | 3239 | final boolean negated = ctx.NOT() != null; |
|
0 commit comments