mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-23 03:24:55 +00:00
Flatten the junctions in the SQM model
This commit is contained in:
parent
71e3b5277a
commit
0a73425520
@ -49,17 +49,16 @@
|
|||||||
import org.hibernate.query.sqm.tree.from.SqmFromClause;
|
import org.hibernate.query.sqm.tree.from.SqmFromClause;
|
||||||
import org.hibernate.query.sqm.tree.from.SqmRoot;
|
import org.hibernate.query.sqm.tree.from.SqmRoot;
|
||||||
import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
|
import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmEmptinessPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmEmptinessPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate;
|
||||||
|
import org.hibernate.query.sqm.tree.predicate.SqmJunctionPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmNegatedPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmNegatedPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmOrPredicate;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
|
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
|
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
|
||||||
@ -598,19 +597,14 @@ public SqmGroupedPredicate visitGroupedPredicate(SqmGroupedPredicate predicate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmAndPredicate visitAndPredicate(SqmAndPredicate predicate) {
|
public SqmJunctionPredicate visitJunctionPredicate(SqmJunctionPredicate predicate) {
|
||||||
return new SqmAndPredicate(
|
final List<SqmPredicate> predicates = new ArrayList<>( predicate.getPredicates().size() );
|
||||||
(SqmPredicate) predicate.getLeftHandPredicate().accept( this ),
|
for ( SqmPredicate subPredicate : predicate.getPredicates() ) {
|
||||||
(SqmPredicate) predicate.getRightHandPredicate().accept( this ),
|
predicates.add( (SqmPredicate) subPredicate.accept( this ) );
|
||||||
getCreationContext().getNodeBuilder()
|
}
|
||||||
);
|
return new SqmJunctionPredicate(
|
||||||
}
|
predicate.getOperator(),
|
||||||
|
predicates,
|
||||||
@Override
|
|
||||||
public SqmOrPredicate visitOrPredicate(SqmOrPredicate predicate) {
|
|
||||||
return new SqmOrPredicate(
|
|
||||||
(SqmPredicate) predicate.getLeftHandPredicate().accept( this ),
|
|
||||||
(SqmPredicate) predicate.getRightHandPredicate().accept( this ),
|
|
||||||
getCreationContext().getNodeBuilder()
|
getCreationContext().getNodeBuilder()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,6 @@
|
|||||||
import org.hibernate.query.sqm.tree.insert.SqmInsertStatement;
|
import org.hibernate.query.sqm.tree.insert.SqmInsertStatement;
|
||||||
import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement;
|
import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement;
|
||||||
import org.hibernate.query.sqm.tree.insert.SqmValues;
|
import org.hibernate.query.sqm.tree.insert.SqmValues;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
||||||
@ -160,12 +159,12 @@
|
|||||||
import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate;
|
||||||
|
import org.hibernate.query.sqm.tree.predicate.SqmJunctionPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmNegatablePredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmNegatablePredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmNegatedPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmNegatedPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmOrPredicate;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
|
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
|
||||||
import org.hibernate.query.sqm.tree.select.AbstractSqmSelectQuery;
|
import org.hibernate.query.sqm.tree.select.AbstractSqmSelectQuery;
|
||||||
@ -191,6 +190,7 @@
|
|||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import jakarta.persistence.criteria.Predicate;
|
||||||
import jakarta.persistence.metamodel.SingularAttribute;
|
import jakarta.persistence.metamodel.SingularAttribute;
|
||||||
import org.antlr.v4.runtime.ParserRuleContext;
|
import org.antlr.v4.runtime.ParserRuleContext;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
@ -1784,18 +1784,41 @@ public SqmGroupedPredicate visitGroupedPredicate(HqlParser.GroupedPredicateConte
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPredicate visitAndPredicate(HqlParser.AndPredicateContext ctx) {
|
public SqmPredicate visitAndPredicate(HqlParser.AndPredicateContext ctx) {
|
||||||
return new SqmAndPredicate(
|
return junction(
|
||||||
|
Predicate.BooleanOperator.AND,
|
||||||
(SqmPredicate) ctx.getChild( 0 ).accept( this ),
|
(SqmPredicate) ctx.getChild( 0 ).accept( this ),
|
||||||
(SqmPredicate) ctx.getChild( 2 ).accept( this ),
|
(SqmPredicate) ctx.getChild( 2 ).accept( this )
|
||||||
creationContext.getNodeBuilder()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPredicate visitOrPredicate(HqlParser.OrPredicateContext ctx) {
|
public SqmPredicate visitOrPredicate(HqlParser.OrPredicateContext ctx) {
|
||||||
return new SqmOrPredicate(
|
return junction(
|
||||||
|
Predicate.BooleanOperator.OR,
|
||||||
(SqmPredicate) ctx.getChild( 0 ).accept( this ),
|
(SqmPredicate) ctx.getChild( 0 ).accept( this ),
|
||||||
(SqmPredicate) ctx.getChild( 2 ).accept( this ),
|
(SqmPredicate) ctx.getChild( 2 ).accept( this )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SqmPredicate junction(Predicate.BooleanOperator operator, SqmPredicate lhs, SqmPredicate rhs) {
|
||||||
|
if ( lhs instanceof SqmJunctionPredicate ) {
|
||||||
|
final SqmJunctionPredicate junction = (SqmJunctionPredicate) lhs;
|
||||||
|
if ( junction.getOperator() == operator ) {
|
||||||
|
junction.getPredicates().add( rhs );
|
||||||
|
return junction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( rhs instanceof SqmJunctionPredicate ) {
|
||||||
|
final SqmJunctionPredicate junction = (SqmJunctionPredicate) rhs;
|
||||||
|
if ( junction.getOperator() == operator ) {
|
||||||
|
junction.getPredicates().add( 0, lhs );
|
||||||
|
return junction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new SqmJunctionPredicate(
|
||||||
|
operator,
|
||||||
|
lhs,
|
||||||
|
rhs,
|
||||||
creationContext.getNodeBuilder()
|
creationContext.getNodeBuilder()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,6 @@
|
|||||||
import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
|
import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
|
||||||
import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement;
|
import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement;
|
||||||
import org.hibernate.query.sqm.tree.insert.SqmValues;
|
import org.hibernate.query.sqm.tree.insert.SqmValues;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
||||||
@ -75,11 +74,11 @@
|
|||||||
import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate;
|
||||||
|
import org.hibernate.query.sqm.tree.predicate.SqmJunctionPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmNegatedPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmNegatedPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmOrPredicate;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
|
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
|
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
|
||||||
@ -256,9 +255,7 @@ public interface SemanticQueryWalker<T> {
|
|||||||
|
|
||||||
T visitGroupedPredicate(SqmGroupedPredicate predicate);
|
T visitGroupedPredicate(SqmGroupedPredicate predicate);
|
||||||
|
|
||||||
T visitAndPredicate(SqmAndPredicate predicate);
|
T visitJunctionPredicate(SqmJunctionPredicate predicate);
|
||||||
|
|
||||||
T visitOrPredicate(SqmOrPredicate predicate);
|
|
||||||
|
|
||||||
T visitComparisonPredicate(SqmComparisonPredicate predicate);
|
T visitComparisonPredicate(SqmComparisonPredicate predicate);
|
||||||
|
|
||||||
|
@ -51,7 +51,6 @@
|
|||||||
import org.hibernate.query.criteria.JpaCriteriaQuery;
|
import org.hibernate.query.criteria.JpaCriteriaQuery;
|
||||||
import org.hibernate.query.criteria.JpaExpression;
|
import org.hibernate.query.criteria.JpaExpression;
|
||||||
import org.hibernate.query.criteria.JpaOrder;
|
import org.hibernate.query.criteria.JpaOrder;
|
||||||
import org.hibernate.query.criteria.JpaParameterExpression;
|
|
||||||
import org.hibernate.query.criteria.JpaSelection;
|
import org.hibernate.query.criteria.JpaSelection;
|
||||||
import org.hibernate.query.criteria.ValueHandlingMode;
|
import org.hibernate.query.criteria.ValueHandlingMode;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
@ -90,7 +89,6 @@
|
|||||||
import org.hibernate.query.sqm.tree.expression.SqmUnaryOperation;
|
import org.hibernate.query.sqm.tree.expression.SqmUnaryOperation;
|
||||||
import org.hibernate.query.sqm.tree.from.SqmRoot;
|
import org.hibernate.query.sqm.tree.from.SqmRoot;
|
||||||
import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
|
import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
||||||
@ -99,10 +97,10 @@
|
|||||||
import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmInPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmInPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate;
|
||||||
|
import org.hibernate.query.sqm.tree.predicate.SqmJunctionPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmOrPredicate;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
|
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiationArgument;
|
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiationArgument;
|
||||||
@ -337,13 +335,11 @@ public final SqmPredicate wrap(Expression<Boolean>... expressions) {
|
|||||||
return wrap( expressions[0] );
|
return wrap( expressions[0] );
|
||||||
}
|
}
|
||||||
|
|
||||||
final SqmPredicate lhs = wrap( expressions[0] );
|
final List<SqmPredicate> predicates = new ArrayList<>( expressions.length );
|
||||||
final SqmPredicate rhs = wrap( expressions[1] );
|
for ( Expression<Boolean> expression : expressions ) {
|
||||||
SqmPredicate predicate = new SqmAndPredicate( lhs, rhs, this );
|
predicates.add( wrap( expression ) );
|
||||||
for ( int i = 2; i < expressions.length; i++ ) {
|
|
||||||
predicate = new SqmAndPredicate( predicate, wrap( expressions[i] ), this );
|
|
||||||
}
|
}
|
||||||
return predicate;
|
return new SqmJunctionPredicate( Predicate.BooleanOperator.AND, predicates, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1567,7 +1563,8 @@ public <R> SqmCaseSearched<R> selectCase() {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPredicate and(Expression<Boolean> x, Expression<Boolean> y) {
|
public SqmPredicate and(Expression<Boolean> x, Expression<Boolean> y) {
|
||||||
return new SqmAndPredicate(
|
return new SqmJunctionPredicate(
|
||||||
|
Predicate.BooleanOperator.AND,
|
||||||
wrap( x ),
|
wrap( x ),
|
||||||
wrap( y ),
|
wrap( y ),
|
||||||
this
|
this
|
||||||
@ -1580,17 +1577,17 @@ public SqmPredicate and(Predicate... restrictions) {
|
|||||||
return conjunction();
|
return conjunction();
|
||||||
}
|
}
|
||||||
|
|
||||||
SqmPredicate junction = (SqmPredicate) restrictions[0];
|
final List<SqmPredicate> predicates = new ArrayList<>( restrictions.length );
|
||||||
for ( int i = 1; i < restrictions.length; i++ ) {
|
for ( Predicate expression : restrictions ) {
|
||||||
junction = new SqmAndPredicate( junction, (SqmPredicate) restrictions[i], this );
|
predicates.add( (SqmPredicate) expression );
|
||||||
}
|
}
|
||||||
|
return new SqmJunctionPredicate( Predicate.BooleanOperator.AND, predicates, this );
|
||||||
return junction;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPredicate or(Expression<Boolean> x, Expression<Boolean> y) {
|
public SqmPredicate or(Expression<Boolean> x, Expression<Boolean> y) {
|
||||||
return new SqmOrPredicate(
|
return new SqmJunctionPredicate(
|
||||||
|
Predicate.BooleanOperator.OR,
|
||||||
wrap( x ),
|
wrap( x ),
|
||||||
wrap( y ),
|
wrap( y ),
|
||||||
this
|
this
|
||||||
@ -1603,12 +1600,11 @@ public SqmPredicate or(Predicate... restrictions) {
|
|||||||
return disjunction();
|
return disjunction();
|
||||||
}
|
}
|
||||||
|
|
||||||
SqmPredicate junction = (SqmPredicate) restrictions[0];
|
final List<SqmPredicate> predicates = new ArrayList<>( restrictions.length );
|
||||||
for ( int i = 1; i < restrictions.length; i++ ) {
|
for ( Predicate expression : restrictions ) {
|
||||||
junction = new SqmOrPredicate( junction, (SqmPredicate) restrictions[i], this );
|
predicates.add( (SqmPredicate) expression );
|
||||||
}
|
}
|
||||||
|
return new SqmJunctionPredicate( Predicate.BooleanOperator.OR, predicates, this );
|
||||||
return junction;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,7 +73,6 @@
|
|||||||
import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
|
import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
|
||||||
import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement;
|
import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement;
|
||||||
import org.hibernate.query.sqm.tree.insert.SqmValues;
|
import org.hibernate.query.sqm.tree.insert.SqmValues;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
||||||
@ -82,11 +81,11 @@
|
|||||||
import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate;
|
||||||
|
import org.hibernate.query.sqm.tree.predicate.SqmJunctionPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmNegatedPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmNegatedPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmOrPredicate;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
|
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
|
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
|
||||||
@ -107,6 +106,8 @@
|
|||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import jakarta.persistence.criteria.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Printer for an SQM tree - for debugging purpose
|
* Printer for an SQM tree - for debugging purpose
|
||||||
*
|
*
|
||||||
@ -800,25 +801,13 @@ public Object visitGroupedPredicate(SqmGroupedPredicate predicate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitAndPredicate(SqmAndPredicate predicate) {
|
public Object visitJunctionPredicate(SqmJunctionPredicate predicate) {
|
||||||
processStanza(
|
processStanza(
|
||||||
"and",
|
predicate.getOperator() == Predicate.BooleanOperator.AND ? "and" : "or",
|
||||||
() -> {
|
() -> {
|
||||||
predicate.getLeftHandPredicate().accept( this );
|
for ( SqmPredicate subPredicate : predicate.getPredicates() ) {
|
||||||
predicate.getRightHandPredicate().accept( this );
|
subPredicate.accept( this );
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitOrPredicate(SqmOrPredicate predicate) {
|
|
||||||
processStanza(
|
|
||||||
"or",
|
|
||||||
() -> {
|
|
||||||
predicate.getLeftHandPredicate().accept( this );
|
|
||||||
predicate.getRightHandPredicate().accept( this );
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -72,7 +72,6 @@
|
|||||||
import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
|
import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
|
||||||
import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement;
|
import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement;
|
||||||
import org.hibernate.query.sqm.tree.insert.SqmValues;
|
import org.hibernate.query.sqm.tree.insert.SqmValues;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
||||||
@ -81,11 +80,11 @@
|
|||||||
import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate;
|
||||||
|
import org.hibernate.query.sqm.tree.predicate.SqmJunctionPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmNegatedPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmNegatedPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmOrPredicate;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
|
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
|
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
|
||||||
@ -393,16 +392,10 @@ public Object visitGroupedPredicate(SqmGroupedPredicate predicate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitAndPredicate(SqmAndPredicate predicate) {
|
public Object visitJunctionPredicate(SqmJunctionPredicate predicate) {
|
||||||
predicate.getLeftHandPredicate().accept( this );
|
for ( SqmPredicate subPredicate : predicate.getPredicates() ) {
|
||||||
predicate.getRightHandPredicate().accept( this );
|
subPredicate.accept( this );
|
||||||
return predicate;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object visitOrPredicate(SqmOrPredicate predicate) {
|
|
||||||
predicate.getLeftHandPredicate().accept( this );
|
|
||||||
predicate.getRightHandPredicate().accept( this );
|
|
||||||
return predicate;
|
return predicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,6 @@
|
|||||||
import org.hibernate.query.sqm.tree.insert.SqmInsertStatement;
|
import org.hibernate.query.sqm.tree.insert.SqmInsertStatement;
|
||||||
import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement;
|
import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement;
|
||||||
import org.hibernate.query.sqm.tree.insert.SqmValues;
|
import org.hibernate.query.sqm.tree.insert.SqmValues;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
||||||
@ -227,11 +226,11 @@
|
|||||||
import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate;
|
||||||
|
import org.hibernate.query.sqm.tree.predicate.SqmJunctionPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmNegatedPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmNegatedPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmOrPredicate;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
|
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmAliasedNode;
|
import org.hibernate.query.sqm.tree.select.SqmAliasedNode;
|
||||||
@ -5747,77 +5746,86 @@ public GroupedPredicate visitGroupedPredicate(SqmGroupedPredicate predicate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Junction visitAndPredicate(SqmAndPredicate predicate) {
|
public Junction visitJunctionPredicate(SqmJunctionPredicate predicate) {
|
||||||
final Junction conjunction = new Junction( Junction.Nature.CONJUNCTION, getBooleanType() );
|
if ( predicate.getOperator() == jakarta.persistence.criteria.Predicate.BooleanOperator.AND ) {
|
||||||
conjunction.add( (Predicate) predicate.getLeftHandPredicate().accept( this ) );
|
final List<Predicate> predicates = new ArrayList<>( predicate.getPredicates().size() );
|
||||||
conjunction.add( (Predicate) predicate.getRightHandPredicate().accept( this ) );
|
for ( SqmPredicate subPredicate : predicate.getPredicates() ) {
|
||||||
return conjunction;
|
predicates.add( (Predicate) subPredicate.accept( this ) );
|
||||||
}
|
}
|
||||||
|
return new Junction( Junction.Nature.CONJUNCTION, predicates, getBooleanType() );
|
||||||
|
}
|
||||||
|
final Junction disjunction = new Junction(
|
||||||
|
Junction.Nature.DISJUNCTION,
|
||||||
|
new ArrayList<>( predicate.getPredicates().size() ),
|
||||||
|
getBooleanType()
|
||||||
|
);
|
||||||
|
final List<Map<SqmPath<?>, Set<String>>> conjunctTreatUsagesList = new ArrayList<>( predicate.getPredicates().size() );
|
||||||
|
final Map<SqmPath<?>, Set<String>> conjunctTreatUsagesUnion = new IdentityHashMap<>();
|
||||||
|
boolean hasAnyTreatUsage = false;
|
||||||
|
for ( SqmPredicate subPredicate : predicate.getPredicates() ) {
|
||||||
|
disjunction.add( (Predicate) subPredicate.accept( this ) );
|
||||||
|
if ( conjunctTreatUsages.isEmpty() ) {
|
||||||
|
conjunctTreatUsagesList.add( null );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hasAnyTreatUsage = true;
|
||||||
|
for ( Map.Entry<SqmPath<?>, Set<String>> entry : conjunctTreatUsages.entrySet() ) {
|
||||||
|
conjunctTreatUsagesUnion.computeIfAbsent( entry.getKey(), k -> new HashSet<>() )
|
||||||
|
.addAll( entry.getValue() );
|
||||||
|
}
|
||||||
|
conjunctTreatUsagesList.add( new IdentityHashMap<>( conjunctTreatUsages ) );
|
||||||
|
conjunctTreatUsages.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !hasAnyTreatUsage ) {
|
||||||
|
return disjunction;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
// Build the intersection of the conjunct treat usages,
|
||||||
public Junction visitOrPredicate(SqmOrPredicate predicate) {
|
// so that we can push that up and infer during pruning, which entity subclasses can be omitted
|
||||||
final Junction disjunction = new Junction( Junction.Nature.DISJUNCTION, getBooleanType() );
|
conjunctTreatUsages.putAll( conjunctTreatUsagesUnion );
|
||||||
final Predicate predicate1 = (Predicate) predicate.getLeftHandPredicate().accept( this );
|
|
||||||
final Map<SqmPath<?>, Set<String>> conjunctTreatUsages1;
|
final Iterator<Map.Entry<SqmPath<?>, Set<String>>> iterator = conjunctTreatUsages.entrySet().iterator();
|
||||||
if ( conjunctTreatUsages.isEmpty() ) {
|
while ( iterator.hasNext() ) {
|
||||||
conjunctTreatUsages1 = null;
|
final Map.Entry<SqmPath<?>, Set<String>> entry = iterator.next();
|
||||||
}
|
final Set<String> intersected = new HashSet<>( entry.getValue() );
|
||||||
else {
|
entry.setValue( intersected );
|
||||||
conjunctTreatUsages1 = new IdentityHashMap<>( conjunctTreatUsages );
|
boolean remove = false;
|
||||||
conjunctTreatUsages.clear();
|
for ( Map<SqmPath<?>, Set<String>> conjunctTreatUsages : conjunctTreatUsagesList ) {
|
||||||
}
|
final Set<String> entityNames = conjunctTreatUsages.get( entry.getKey() );
|
||||||
final Predicate predicate2 = (Predicate) predicate.getRightHandPredicate().accept( this );
|
if ( entityNames == null ) {
|
||||||
if ( conjunctTreatUsages.isEmpty() || conjunctTreatUsages1 == null ) {
|
remove = true;
|
||||||
disjunction.add(
|
|
||||||
SqlAstTreeHelper.combinePredicates(
|
|
||||||
consumeConjunctTreatTypeRestrictions( conjunctTreatUsages1 ),
|
|
||||||
predicate1
|
|
||||||
)
|
|
||||||
);
|
|
||||||
disjunction.add( predicate2 );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// If both disjunctions have treat type restrictions build the intersection of the two,
|
|
||||||
// so that we can push that up and infer during pruning, which entity subclasses can be omitted
|
|
||||||
final Map<SqmPath<?>, Set<String>> conjunctTreatUsages2 = new IdentityHashMap<>( conjunctTreatUsages );
|
|
||||||
final Iterator<Map.Entry<SqmPath<?>, Set<String>>> iterator = conjunctTreatUsages.entrySet().iterator();
|
|
||||||
while ( iterator.hasNext() ) {
|
|
||||||
final Map.Entry<SqmPath<?>, Set<String>> entry = iterator.next();
|
|
||||||
final Set<String> entityNames1 = conjunctTreatUsages1.get( entry.getKey() );
|
|
||||||
if ( entityNames1 == null ) {
|
|
||||||
iterator.remove();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Intersect the two sets and transfer the common elements to the intersection
|
// Intersect the two sets and transfer the common elements to the intersection
|
||||||
final Set<String> entityNames2 = entry.getValue();
|
intersected.retainAll( entityNames );
|
||||||
final Set<String> intersected = new HashSet<>( entityNames1 );
|
|
||||||
intersected.retainAll( entityNames2 );
|
|
||||||
if ( intersected.isEmpty() ) {
|
if ( intersected.isEmpty() ) {
|
||||||
iterator.remove();
|
remove = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
entry.setValue( intersected );
|
entityNames.removeAll( intersected );
|
||||||
entityNames1.removeAll( intersected );
|
if ( entityNames.isEmpty() ) {
|
||||||
entityNames2.removeAll( intersected );
|
conjunctTreatUsages.remove( entry.getKey() );
|
||||||
if ( entityNames1.isEmpty() ) {
|
|
||||||
conjunctTreatUsages1.remove( entry.getKey() );
|
|
||||||
}
|
|
||||||
if ( entityNames2.isEmpty() ) {
|
|
||||||
conjunctTreatUsages2.remove( entry.getKey() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
disjunction.add(
|
|
||||||
SqlAstTreeHelper.combinePredicates(
|
if ( remove ) {
|
||||||
consumeConjunctTreatTypeRestrictions( conjunctTreatUsages1 ),
|
iterator.remove();
|
||||||
predicate1
|
}
|
||||||
)
|
}
|
||||||
);
|
|
||||||
disjunction.add(
|
// Prepend the treat type usages to the respective conjuncts
|
||||||
SqlAstTreeHelper.combinePredicates(
|
for ( int i = 0; i < conjunctTreatUsagesList.size(); i++ ) {
|
||||||
consumeConjunctTreatTypeRestrictions( conjunctTreatUsages2 ),
|
final Map<SqmPath<?>, Set<String>> conjunctTreatUsages = conjunctTreatUsagesList.get( i );
|
||||||
predicate2
|
if ( conjunctTreatUsages != null ) {
|
||||||
)
|
disjunction.getPredicates().set(
|
||||||
);
|
i,
|
||||||
|
SqlAstTreeHelper.combinePredicates(
|
||||||
|
consumeConjunctTreatTypeRestrictions( conjunctTreatUsages ),
|
||||||
|
disjunction.getPredicates().get( i )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return disjunction;
|
return disjunction;
|
||||||
}
|
}
|
||||||
|
@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
|
||||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
|
||||||
*/
|
|
||||||
package org.hibernate.query.sqm.tree.predicate;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.hibernate.query.sqm.NodeBuilder;
|
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
|
||||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
|
||||||
|
|
||||||
import jakarta.persistence.criteria.Expression;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class SqmAndPredicate extends AbstractSqmPredicate implements SqmJunctivePredicate {
|
|
||||||
private final SqmPredicate leftHandPredicate;
|
|
||||||
private final SqmPredicate rightHandPredicate;
|
|
||||||
|
|
||||||
public SqmAndPredicate(
|
|
||||||
SqmPredicate leftHandPredicate,
|
|
||||||
SqmPredicate rightHandPredicate,
|
|
||||||
NodeBuilder nodeBuilder) {
|
|
||||||
super( leftHandPredicate.getExpressible(), nodeBuilder );
|
|
||||||
this.leftHandPredicate = leftHandPredicate;
|
|
||||||
this.rightHandPredicate = rightHandPredicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqmAndPredicate copy(SqmCopyContext context) {
|
|
||||||
final SqmAndPredicate existing = context.getCopy( this );
|
|
||||||
if ( existing != null ) {
|
|
||||||
return existing;
|
|
||||||
}
|
|
||||||
final SqmAndPredicate predicate = context.registerCopy(
|
|
||||||
this,
|
|
||||||
new SqmAndPredicate(
|
|
||||||
leftHandPredicate.copy( context ),
|
|
||||||
rightHandPredicate.copy( context ),
|
|
||||||
nodeBuilder()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
copyTo( predicate, context );
|
|
||||||
return predicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqmPredicate getLeftHandPredicate() {
|
|
||||||
return leftHandPredicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqmPredicate getRightHandPredicate() {
|
|
||||||
return rightHandPredicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T accept(SemanticQueryWalker<T> walker) {
|
|
||||||
return walker.visitAndPredicate( this );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BooleanOperator getOperator() {
|
|
||||||
return BooleanOperator.AND;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isNegated() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Expression<Boolean>> getExpressions() {
|
|
||||||
return Arrays.asList( leftHandPredicate, rightHandPredicate );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqmPredicate not() {
|
|
||||||
return new SqmNegatedPredicate( this, nodeBuilder() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void appendHqlString(StringBuilder sb) {
|
|
||||||
if ( leftHandPredicate instanceof SqmOrPredicate ) {
|
|
||||||
sb.append( '(' );
|
|
||||||
leftHandPredicate.appendHqlString( sb );
|
|
||||||
sb.append( ')' );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
leftHandPredicate.appendHqlString( sb );
|
|
||||||
}
|
|
||||||
sb.append( " and " );
|
|
||||||
if ( rightHandPredicate instanceof SqmOrPredicate ) {
|
|
||||||
sb.append( '(' );
|
|
||||||
rightHandPredicate.appendHqlString( sb );
|
|
||||||
sb.append( ')' );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rightHandPredicate.appendHqlString( sb );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.query.sqm.tree.predicate;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.query.sqm.NodeBuilder;
|
||||||
|
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||||
|
import org.hibernate.query.sqm.SqmExpressible;
|
||||||
|
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||||
|
import org.hibernate.sql.ast.tree.predicate.Junction;
|
||||||
|
|
||||||
|
import jakarta.persistence.criteria.Expression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class SqmJunctionPredicate extends AbstractSqmPredicate {
|
||||||
|
private final BooleanOperator booleanOperator;
|
||||||
|
private final List<SqmPredicate> predicates;
|
||||||
|
|
||||||
|
public SqmJunctionPredicate(
|
||||||
|
BooleanOperator booleanOperator,
|
||||||
|
SqmPredicate leftHandPredicate,
|
||||||
|
SqmPredicate rightHandPredicate,
|
||||||
|
NodeBuilder nodeBuilder) {
|
||||||
|
super( leftHandPredicate.getExpressible(), nodeBuilder );
|
||||||
|
this.booleanOperator = booleanOperator;
|
||||||
|
this.predicates = new ArrayList<>( 2 );
|
||||||
|
this.predicates.add( leftHandPredicate );
|
||||||
|
this.predicates.add( rightHandPredicate );
|
||||||
|
}
|
||||||
|
|
||||||
|
public SqmJunctionPredicate(
|
||||||
|
BooleanOperator booleanOperator,
|
||||||
|
List<SqmPredicate> predicates,
|
||||||
|
NodeBuilder nodeBuilder) {
|
||||||
|
super( predicates.get( 0 ).getNodeType(), nodeBuilder );
|
||||||
|
this.booleanOperator = booleanOperator;
|
||||||
|
this.predicates = predicates;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqmJunctionPredicate copy(SqmCopyContext context) {
|
||||||
|
final SqmJunctionPredicate existing = context.getCopy( this );
|
||||||
|
if ( existing != null ) {
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
final List<SqmPredicate> predicates = new ArrayList<>( this.predicates.size() );
|
||||||
|
for ( SqmPredicate predicate : this.predicates ) {
|
||||||
|
predicates.add( predicate.copy( context ) );
|
||||||
|
}
|
||||||
|
final SqmJunctionPredicate predicate = context.registerCopy(
|
||||||
|
this,
|
||||||
|
new SqmJunctionPredicate(
|
||||||
|
booleanOperator,
|
||||||
|
predicates,
|
||||||
|
nodeBuilder()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
copyTo( predicate, context );
|
||||||
|
return predicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SqmPredicate> getPredicates() {
|
||||||
|
return predicates;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T accept(SemanticQueryWalker<T> walker) {
|
||||||
|
return walker.visitJunctionPredicate( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BooleanOperator getOperator() {
|
||||||
|
return booleanOperator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNegated() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Expression<Boolean>> getExpressions() {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (List<Expression<Boolean>>) (List<?>) predicates;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqmPredicate not() {
|
||||||
|
return new SqmNegatedPredicate( this, nodeBuilder() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendHqlString(StringBuilder sb) {
|
||||||
|
final String separator = booleanOperator == BooleanOperator.AND
|
||||||
|
? " and "
|
||||||
|
: " or ";
|
||||||
|
appendJunctionHqlString( predicates.get( 0 ), sb );
|
||||||
|
for ( int i = 1; i < predicates.size(); i++ ) {
|
||||||
|
sb.append( separator );
|
||||||
|
appendJunctionHqlString( predicates.get( i ), sb );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendJunctionHqlString(SqmPredicate p, StringBuilder sb) {
|
||||||
|
if ( p instanceof SqmJunctionPredicate ) {
|
||||||
|
final SqmJunctionPredicate junction = (SqmJunctionPredicate) p;
|
||||||
|
// If we have the same nature, or if this is a disjunction and the operand is a conjunction,
|
||||||
|
// then we don't need parenthesis, because the AND operator binds stronger
|
||||||
|
if ( booleanOperator == junction.getOperator() || booleanOperator == BooleanOperator.OR ) {
|
||||||
|
junction.appendHqlString( sb );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sb.append( '(' );
|
||||||
|
junction.appendHqlString( sb );
|
||||||
|
sb.append( ')' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p.appendHqlString( sb );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
|
||||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
|
||||||
*/
|
|
||||||
package org.hibernate.query.sqm.tree.predicate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public interface SqmJunctivePredicate extends SqmPredicate {
|
|
||||||
SqmPredicate getLeftHandPredicate();
|
|
||||||
|
|
||||||
SqmPredicate getRightHandPredicate();
|
|
||||||
}
|
|
@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
|
||||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
|
||||||
*/
|
|
||||||
package org.hibernate.query.sqm.tree.predicate;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.hibernate.query.sqm.NodeBuilder;
|
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
|
||||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.AbstractSqmExpression;
|
|
||||||
|
|
||||||
import jakarta.persistence.criteria.Expression;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class SqmOrPredicate extends AbstractSqmExpression<Boolean> implements SqmJunctivePredicate {
|
|
||||||
private final SqmPredicate leftHandPredicate;
|
|
||||||
private final SqmPredicate rightHandPredicate;
|
|
||||||
|
|
||||||
public SqmOrPredicate(
|
|
||||||
SqmPredicate leftHandPredicate,
|
|
||||||
SqmPredicate rightHandPredicate,
|
|
||||||
NodeBuilder nodeBuilder) {
|
|
||||||
super( null, nodeBuilder );
|
|
||||||
this.leftHandPredicate = leftHandPredicate;
|
|
||||||
this.rightHandPredicate = rightHandPredicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqmOrPredicate copy(SqmCopyContext context) {
|
|
||||||
final SqmOrPredicate existing = context.getCopy( this );
|
|
||||||
if ( existing != null ) {
|
|
||||||
return existing;
|
|
||||||
}
|
|
||||||
final SqmOrPredicate predicate = context.registerCopy(
|
|
||||||
this,
|
|
||||||
new SqmOrPredicate(
|
|
||||||
leftHandPredicate.copy( context ),
|
|
||||||
rightHandPredicate.copy( context ),
|
|
||||||
nodeBuilder()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
copyTo( predicate, context );
|
|
||||||
return predicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqmPredicate getLeftHandPredicate() {
|
|
||||||
return leftHandPredicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqmPredicate getRightHandPredicate() {
|
|
||||||
return rightHandPredicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T accept(SemanticQueryWalker<T> walker) {
|
|
||||||
return walker.visitOrPredicate( this );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqmPredicate not() {
|
|
||||||
return new SqmNegatedPredicate( this, nodeBuilder() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BooleanOperator getOperator() {
|
|
||||||
return BooleanOperator.OR;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isNegated() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Expression<Boolean>> getExpressions() {
|
|
||||||
return Arrays.asList( leftHandPredicate, rightHandPredicate );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void appendHqlString(StringBuilder sb) {
|
|
||||||
if ( leftHandPredicate instanceof SqmAndPredicate ) {
|
|
||||||
sb.append( '(' );
|
|
||||||
leftHandPredicate.appendHqlString( sb );
|
|
||||||
sb.append( ')' );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
leftHandPredicate.appendHqlString( sb );
|
|
||||||
}
|
|
||||||
sb.append( " or " );
|
|
||||||
if ( rightHandPredicate instanceof SqmAndPredicate ) {
|
|
||||||
sb.append( '(' );
|
|
||||||
rightHandPredicate.appendHqlString( sb );
|
|
||||||
sb.append( ')' );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rightHandPredicate.appendHqlString( sb );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user