|
30 | 30 | import java.util.Set; |
31 | 31 |
|
32 | 32 | import jakarta.persistence.criteria.Nulls; |
| 33 | +import org.antlr.v4.runtime.Token; |
33 | 34 | import org.hibernate.AssertionFailure; |
34 | 35 | import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; |
35 | 36 | import org.hibernate.cfg.QuerySettings; |
@@ -2425,6 +2426,91 @@ public SqmPredicate visitUnaryIsPredicate(HqlParser.UnaryIsPredicateContext ctx) |
2425 | 2426 | }; |
2426 | 2427 | } |
2427 | 2428 |
|
| 2429 | + @Override |
| 2430 | + public SqmPredicate visitBinaryExpressionPredicate(HqlParser.BinaryExpressionPredicateContext ctx) { |
| 2431 | + final var firstSymbol = ((TerminalNode) ctx.getChild( 1 )).getSymbol(); |
| 2432 | + final boolean negated; |
| 2433 | + final Token operationSymbol; |
| 2434 | + if ( firstSymbol.getType() == HqlParser.NOT ) { |
| 2435 | + negated = true; |
| 2436 | + operationSymbol = ((TerminalNode) ctx.getChild( 2 )).getSymbol(); |
| 2437 | + } |
| 2438 | + else { |
| 2439 | + negated = false; |
| 2440 | + operationSymbol = firstSymbol; |
| 2441 | + } |
| 2442 | + final var expressions = ctx.expression(); |
| 2443 | + final var lhsCtx = expressions.get( 0 ); |
| 2444 | + final var rhsCtx = expressions.get( 1 ); |
| 2445 | + return switch ( operationSymbol.getType() ) { |
| 2446 | + case HqlParser.CONTAINS -> { |
| 2447 | + final var lhs = (SqmExpression<?>) lhsCtx.accept( this ); |
| 2448 | + final var rhs = (SqmExpression<?>) rhsCtx.accept( this ); |
| 2449 | + final var lhsExpressible = lhs.getExpressible(); |
| 2450 | + if ( lhsExpressible != null && !(lhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
| 2451 | + throw new SemanticException( |
| 2452 | + "First operand for contains predicate must be a basic plural type expression, but found: " + lhsExpressible.getSqmType(), |
| 2453 | + query |
| 2454 | + ); |
| 2455 | + } |
| 2456 | + final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( |
| 2457 | + "array_contains" ).generateSqmExpression( |
| 2458 | + asList( lhs, rhs ), |
| 2459 | + null, |
| 2460 | + queryEngine() |
| 2461 | + ); |
| 2462 | + yield new SqmBooleanExpressionPredicate( contains, negated, nodeBuilder() ); |
| 2463 | + } |
| 2464 | + case HqlParser.INCLUDES -> { |
| 2465 | + final var lhs = (SqmExpression<?>) lhsCtx.accept( this ); |
| 2466 | + final var rhs = (SqmExpression<?>) rhsCtx.accept( this ); |
| 2467 | + final var lhsExpressible = lhs.getExpressible(); |
| 2468 | + final var rhsExpressible = rhs.getExpressible(); |
| 2469 | + if ( lhsExpressible != null && !( lhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
| 2470 | + throw new SemanticException( |
| 2471 | + "First operand for includes predicate must be a basic plural type expression, but found: " |
| 2472 | + + lhsExpressible.getSqmType(), |
| 2473 | + query |
| 2474 | + ); |
| 2475 | + } |
| 2476 | + if ( rhsExpressible != null && !( rhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
| 2477 | + throw new SemanticException( |
| 2478 | + "Second operand for includes predicate must be a basic plural type expression, but found: " |
| 2479 | + + rhsExpressible.getSqmType(), |
| 2480 | + query |
| 2481 | + ); |
| 2482 | + } |
| 2483 | + final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( "array_includes" ).generateSqmExpression( |
| 2484 | + asList( lhs, rhs ), |
| 2485 | + null, |
| 2486 | + queryEngine() |
| 2487 | + ); |
| 2488 | + yield new SqmBooleanExpressionPredicate( contains, negated, nodeBuilder() ); |
| 2489 | + } |
| 2490 | + case HqlParser.INTERSECTS -> { |
| 2491 | + final var lhs = (SqmExpression<?>) lhsCtx.accept( this ); |
| 2492 | + final var rhs = (SqmExpression<?>) rhsCtx.accept( this ); |
| 2493 | + final var lhsExpressible = lhs.getExpressible(); |
| 2494 | + if ( lhsExpressible != null && !( lhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
| 2495 | + throw new SemanticException( |
| 2496 | + "First operand for intersects predicate must be a basic plural type expression, but found: " |
| 2497 | + + lhsExpressible.getSqmType(), |
| 2498 | + query |
| 2499 | + ); |
| 2500 | + } |
| 2501 | + final SelfRenderingSqmFunction<Boolean> contains = |
| 2502 | + getFunctionDescriptor( "array_intersects" ) |
| 2503 | + .generateSqmExpression( |
| 2504 | + asList( lhs, rhs ), |
| 2505 | + null, |
| 2506 | + queryEngine() |
| 2507 | + ); |
| 2508 | + yield new SqmBooleanExpressionPredicate( contains, negated, nodeBuilder() ); |
| 2509 | + } |
| 2510 | + default -> throw new AssertionError( "Unknown binary expression predicate: " + operationSymbol ); |
| 2511 | + }; |
| 2512 | + } |
| 2513 | + |
2428 | 2514 | @Override |
2429 | 2515 | public Object visitComparisonOperator(HqlParser.ComparisonOperatorContext ctx) { |
2430 | 2516 | final var firstToken = (TerminalNode) ctx.getChild( 0 ); |
@@ -2573,27 +2659,6 @@ private String getPossibleEnumValue(HqlParser.ExpressionContext expressionContex |
2573 | 2659 | return null; |
2574 | 2660 | } |
2575 | 2661 |
|
2576 | | - @Override |
2577 | | - public SqmPredicate visitContainsPredicate(HqlParser.ContainsPredicateContext ctx) { |
2578 | | - final boolean negated = ctx.NOT() != null; |
2579 | | - final var lhs = (SqmExpression<?>) ctx.expression( 0 ).accept( this ); |
2580 | | - final var rhs = (SqmExpression<?>) ctx.expression( 1 ).accept( this ); |
2581 | | - final var lhsExpressible = lhs.getExpressible(); |
2582 | | - if ( lhsExpressible != null |
2583 | | - && !( lhsExpressible.getSqmType() instanceof BasicPluralType<?, ?> ) ) { |
2584 | | - throw new SemanticException( |
2585 | | - "First operand for contains predicate must be a basic plural type expression, but found: " + lhsExpressible.getSqmType(), |
2586 | | - query |
2587 | | - ); |
2588 | | - } |
2589 | | - final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( "array_contains" ).generateSqmExpression( |
2590 | | - asList( lhs, rhs ), |
2591 | | - null, |
2592 | | - queryEngine() |
2593 | | - ); |
2594 | | - return new SqmBooleanExpressionPredicate( contains, negated, nodeBuilder() ); |
2595 | | - } |
2596 | | - |
2597 | 2662 | @Override |
2598 | 2663 | public SqmExpression<?> visitJsonValueFunction(HqlParser.JsonValueFunctionContext ctx) { |
2599 | 2664 | checkJsonFunctionsEnabled( ctx ); |
@@ -3128,58 +3193,6 @@ private void checkXmlFunctionsEnabled(ParserRuleContext ctx) { |
3128 | 3193 | } |
3129 | 3194 | } |
3130 | 3195 |
|
3131 | | - @Override |
3132 | | - public SqmPredicate visitIncludesPredicate(HqlParser.IncludesPredicateContext ctx) { |
3133 | | - final boolean negated = ctx.NOT() != null; |
3134 | | - final var lhs = (SqmExpression<?>) ctx.expression( 0 ).accept( this ); |
3135 | | - final var rhs = (SqmExpression<?>) ctx.expression( 1 ).accept( this ); |
3136 | | - final var lhsExpressible = lhs.getExpressible(); |
3137 | | - final var rhsExpressible = rhs.getExpressible(); |
3138 | | - if ( lhsExpressible != null && !( lhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
3139 | | - throw new SemanticException( |
3140 | | - "First operand for includes predicate must be a basic plural type expression, but found: " |
3141 | | - + lhsExpressible.getSqmType(), |
3142 | | - query |
3143 | | - ); |
3144 | | - } |
3145 | | - if ( rhsExpressible != null && !( rhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
3146 | | - throw new SemanticException( |
3147 | | - "Second operand for includes predicate must be a basic plural type expression, but found: " |
3148 | | - + rhsExpressible.getSqmType(), |
3149 | | - query |
3150 | | - ); |
3151 | | - } |
3152 | | - final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( "array_includes" ).generateSqmExpression( |
3153 | | - asList( lhs, rhs ), |
3154 | | - null, |
3155 | | - queryEngine() |
3156 | | - ); |
3157 | | - return new SqmBooleanExpressionPredicate( contains, negated, nodeBuilder() ); |
3158 | | - } |
3159 | | - |
3160 | | - @Override |
3161 | | - public SqmPredicate visitIntersectsPredicate(HqlParser.IntersectsPredicateContext ctx) { |
3162 | | - final boolean negated = ctx.NOT() != null; |
3163 | | - final var lhs = (SqmExpression<?>) ctx.expression( 0 ).accept( this ); |
3164 | | - final var rhs = (SqmExpression<?>) ctx.expression( 1 ).accept( this ); |
3165 | | - final var lhsExpressible = lhs.getExpressible(); |
3166 | | - if ( lhsExpressible != null && !( lhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { |
3167 | | - throw new SemanticException( |
3168 | | - "First operand for intersects predicate must be a basic plural type expression, but found: " |
3169 | | - + lhsExpressible.getSqmType(), |
3170 | | - query |
3171 | | - ); |
3172 | | - } |
3173 | | - final SelfRenderingSqmFunction<Boolean> contains = |
3174 | | - getFunctionDescriptor( "array_intersects" ) |
3175 | | - .generateSqmExpression( |
3176 | | - asList( lhs, rhs ), |
3177 | | - null, |
3178 | | - queryEngine() |
3179 | | - ); |
3180 | | - return new SqmBooleanExpressionPredicate( contains, negated, nodeBuilder() ); |
3181 | | - } |
3182 | | - |
3183 | 3196 | @Override |
3184 | 3197 | public SqmPredicate visitLikePredicate(HqlParser.LikePredicateContext ctx) { |
3185 | 3198 | final boolean negated = ctx.NOT() != null; |
|
0 commit comments