diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/HibernateCriteriaBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/HibernateCriteriaBuilder.java index bf15aed2da..a2415b828e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/HibernateCriteriaBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/HibernateCriteriaBuilder.java @@ -187,30 +187,8 @@ public interface HibernateCriteriaBuilder extends CriteriaBuilder { @Override JpaCriteriaQuery union(CriteriaQuery left, CriteriaQuery right); - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - default JpaCriteriaQuery unionAll(CriteriaQuery left, CriteriaQuery right) { - // for now at least... - assert left instanceof SqmSelectStatement; - final SqmSelectStatement leftSqm = (SqmSelectStatement) left; - final SqmSelectStatement rightSqm = (SqmSelectStatement) right; - - - // SqmQueryGroup is the UNION ALL between the two - final SqmQueryGroup sqmQueryGroup = new SqmQueryGroup( - leftSqm.nodeBuilder(), - SetOperator.UNION_ALL, - List.of( leftSqm.getQueryPart(), rightSqm.getQueryPart() ) - ); - - final SqmSelectStatement sqmSelectStatement = new SqmSelectStatement<>( - leftSqm.getResultType(), - SqmQuerySource.CRITERIA, - leftSqm.nodeBuilder() - ); - sqmSelectStatement.setQueryPart( sqmQueryGroup ); - return sqmSelectStatement; - } + JpaCriteriaQuery unionAll(CriteriaQuery left, CriteriaQuery right); default JpaSubQuery union(Subquery query1, Subquery... queries) { return union( false, query1, queries ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java index ac3de08145..9f721cccfe 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java @@ -549,43 +549,117 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, @Override public JpaCriteriaQuery union(CriteriaQuery left, CriteriaQuery right) { - // todo (jpa 3.2) : implement - throw new UnsupportedOperationException( "Not yet implemented" ); + return createUnionSet( SetOperator.UNION, left, right ); } @Override public JpaCriteriaQuery unionAll(CriteriaQuery left, CriteriaQuery right) { - // todo (jpa 3.2) : implement - throw new UnsupportedOperationException( "Not yet implemented" ); + return createUnionSet( SetOperator.UNION_ALL, left, right ); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private static JpaCriteriaQuery createUnionSet( + SetOperator operator, + CriteriaQuery left, + CriteriaQuery right) { + assert operator == SetOperator.UNION || operator == SetOperator.UNION_ALL; + assert left instanceof SqmSelectStatement; + assert right instanceof SqmSelectStatement; + final SqmSelectStatement leftSqm = (SqmSelectStatement) left; + final SqmSelectStatement rightSqm = (SqmSelectStatement) right; + + // SqmQueryGroup is the UNION ALL between the two + final SqmQueryGroup sqmQueryGroup = new SqmQueryGroup( + leftSqm.nodeBuilder(), + operator, + List.of( leftSqm.getQueryPart(), rightSqm.getQueryPart() ) + ); + + final SqmSelectStatement sqmSelectStatement = new SqmSelectStatement<>( + leftSqm.getResultType(), + SqmQuerySource.CRITERIA, + leftSqm.nodeBuilder() + ); + sqmSelectStatement.setQueryPart( sqmQueryGroup ); + return sqmSelectStatement; } @Override public JpaCriteriaQuery intersect(CriteriaQuery left, CriteriaQuery right) { - // todo (jpa 3.2) : implement - throw new UnsupportedOperationException( "Not yet implemented" ); + return createIntersectSet( SetOperator.INTERSECT, left, right ); } @Override public JpaCriteriaQuery intersectAll(CriteriaQuery left, CriteriaQuery right) { - // todo (jpa 3.2) : implement - throw new UnsupportedOperationException( "Not yet implemented" ); + return createIntersectSet( SetOperator.INTERSECT_ALL, left, right ); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private static JpaCriteriaQuery createIntersectSet( + SetOperator operator, + CriteriaQuery left, + CriteriaQuery right) { + assert operator == SetOperator.INTERSECT || operator == SetOperator.INTERSECT_ALL; + assert left instanceof SqmSelectStatement; + assert right instanceof SqmSelectStatement; + final SqmSelectStatement leftSqm = (SqmSelectStatement) left; + final SqmSelectStatement rightSqm = (SqmSelectStatement) right; + + // SqmQueryGroup is the UNION ALL between the two + final SqmQueryGroup sqmQueryGroup = new SqmQueryGroup( + leftSqm.nodeBuilder(), + operator, + List.of( leftSqm.getQueryPart(), rightSqm.getQueryPart() ) + ); + + final SqmSelectStatement sqmSelectStatement = new SqmSelectStatement<>( + leftSqm.getResultType(), + SqmQuerySource.CRITERIA, + leftSqm.nodeBuilder() + ); + sqmSelectStatement.setQueryPart( sqmQueryGroup ); + return sqmSelectStatement; } @Override public JpaCriteriaQuery except(CriteriaQuery left, CriteriaQuery right) { - // todo (jpa 3.2) : implement - throw new UnsupportedOperationException( "Not yet implemented" ); + return createExceptSet( SetOperator.EXCEPT, left, right ); } @Override public JpaCriteriaQuery exceptAll(CriteriaQuery left, CriteriaQuery right) { - // todo (jpa 3.2) : implement - throw new UnsupportedOperationException( "Not yet implemented" ); + return createExceptSet( SetOperator.EXCEPT_ALL, left, right ); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private static JpaCriteriaQuery createExceptSet( + SetOperator operator, + CriteriaQuery left, + CriteriaQuery right) { + assert operator == SetOperator.EXCEPT || operator == SetOperator.EXCEPT_ALL; + assert left instanceof SqmSelectStatement; + assert right instanceof SqmSelectStatement; + final SqmSelectStatement leftSqm = (SqmSelectStatement) left; + final SqmSelectStatement rightSqm = (SqmSelectStatement) right; + + // SqmQueryGroup is the UNION ALL between the two + final SqmQueryGroup sqmQueryGroup = new SqmQueryGroup( + leftSqm.nodeBuilder(), + operator, + List.of( leftSqm.getQueryPart(), rightSqm.getQueryPart() ) + ); + + final SqmSelectStatement sqmSelectStatement = new SqmSelectStatement<>( + leftSqm.getResultType(), + SqmQuerySource.CRITERIA, + leftSqm.nodeBuilder() + ); + sqmSelectStatement.setQueryPart( sqmQueryGroup ); + return sqmSelectStatement; } @Override public SqmSingularJoin treat(Join join, Class type) { - //noinspection unchecked return (SqmTreatedSingularJoin) ( (SqmSingularJoin) join ).treatAs( type ); }