HHH-18178 Validation of CTE source query in `with` method
This commit is contained in:
parent
726ae6a959
commit
edc7b5d680
|
@ -784,10 +784,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
final HqlParser.QueryExpressionContext queryExpressionContext = (HqlParser.QueryExpressionContext) ctx.getChild( queryExpressionIndex );
|
final HqlParser.QueryExpressionContext queryExpressionContext = (HqlParser.QueryExpressionContext) ctx.getChild( queryExpressionIndex );
|
||||||
final SqmSelectQuery<Object> cte;
|
final SqmSelectQuery<Object> cte;
|
||||||
if ( cteContainer instanceof SqmSubQuery<?> ) {
|
if ( cteContainer instanceof SqmSubQuery<?> ) {
|
||||||
cte = new SqmSubQuery<>(
|
cte = new SqmSubQuery<>( ( (SqmSubQuery<?>) cteContainer ).getParent(), creationContext.getNodeBuilder() );
|
||||||
processingStateStack.getCurrent().getProcessingQuery(),
|
|
||||||
creationContext.getNodeBuilder()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cte = new SqmSelectStatement<>( creationContext.getNodeBuilder() );
|
cte = new SqmSelectStatement<>( creationContext.getNodeBuilder() );
|
||||||
|
|
|
@ -168,7 +168,7 @@ public abstract class AbstractSqmSelectQuery<T>
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <X> JpaCteCriteria<X> withInternal(String name, AbstractQuery<X> criteria) {
|
protected <X> JpaCteCriteria<X> withInternal(String name, AbstractQuery<X> criteria) {
|
||||||
final SqmCteStatement<X> cteStatement = new SqmCteStatement<>(
|
final SqmCteStatement<X> cteStatement = new SqmCteStatement<>(
|
||||||
name,
|
name,
|
||||||
(SqmSelectQuery<X>) criteria,
|
(SqmSelectQuery<X>) criteria,
|
||||||
|
@ -181,7 +181,7 @@ public abstract class AbstractSqmSelectQuery<T>
|
||||||
return cteStatement;
|
return cteStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <X> JpaCteCriteria<X> withInternal(
|
protected <X> JpaCteCriteria<X> withInternal(
|
||||||
String name,
|
String name,
|
||||||
AbstractQuery<X> baseCriteria,
|
AbstractQuery<X> baseCriteria,
|
||||||
boolean unionDistinct,
|
boolean unionDistinct,
|
||||||
|
|
|
@ -11,10 +11,12 @@ import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.hibernate.Internal;
|
import org.hibernate.Internal;
|
||||||
import org.hibernate.query.criteria.JpaCriteriaQuery;
|
import org.hibernate.query.criteria.JpaCriteriaQuery;
|
||||||
|
import org.hibernate.query.criteria.JpaCteCriteria;
|
||||||
import org.hibernate.query.criteria.JpaExpression;
|
import org.hibernate.query.criteria.JpaExpression;
|
||||||
import org.hibernate.query.criteria.JpaSelection;
|
import org.hibernate.query.criteria.JpaSelection;
|
||||||
import org.hibernate.query.sqm.FetchClauseType;
|
import org.hibernate.query.sqm.FetchClauseType;
|
||||||
|
@ -32,6 +34,7 @@ import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.query.sqm.tree.from.SqmRoot;
|
import org.hibernate.query.sqm.tree.from.SqmRoot;
|
||||||
|
|
||||||
import jakarta.persistence.Tuple;
|
import jakarta.persistence.Tuple;
|
||||||
|
import jakarta.persistence.criteria.AbstractQuery;
|
||||||
import jakarta.persistence.criteria.Expression;
|
import jakarta.persistence.criteria.Expression;
|
||||||
import jakarta.persistence.criteria.Order;
|
import jakarta.persistence.criteria.Order;
|
||||||
import jakarta.persistence.criteria.ParameterExpression;
|
import jakarta.persistence.criteria.ParameterExpression;
|
||||||
|
@ -252,6 +255,31 @@ public class SqmSelectStatement<T> extends AbstractSqmSelectQuery<T> implements
|
||||||
parameters.add( parameter );
|
parameters.add( parameter );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected <X> JpaCteCriteria<X> withInternal(String name, AbstractQuery<X> criteria) {
|
||||||
|
if ( criteria instanceof SqmSubQuery<?> ) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid query type provided to root query 'with' method, " +
|
||||||
|
"expecting a root query to use as CTE instead found a subquery"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return super.withInternal( name, criteria );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected <X> JpaCteCriteria<X> withInternal(
|
||||||
|
String name,
|
||||||
|
AbstractQuery<X> baseCriteria,
|
||||||
|
boolean unionDistinct,
|
||||||
|
Function<JpaCteCriteria<X>, AbstractQuery<X>> recursiveCriteriaProducer) {
|
||||||
|
if ( baseCriteria instanceof SqmSubQuery<?> ) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid query type provided to root query 'with' method, " +
|
||||||
|
"expecting a root query to use as CTE instead found a subquery"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return super.withInternal( name, baseCriteria, unionDistinct, recursiveCriteriaProducer );
|
||||||
|
}
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// JPA
|
// JPA
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||||
import org.hibernate.query.criteria.JpaCrossJoin;
|
import org.hibernate.query.criteria.JpaCrossJoin;
|
||||||
|
@ -201,6 +202,32 @@ public class SqmSubQuery<T> extends AbstractSqmSelectQuery<T> implements SqmSele
|
||||||
return ( (JpaCteContainer) parent ).getCteCriteria( cteName );
|
return ( (JpaCteContainer) parent ).getCteCriteria( cteName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected <X> JpaCteCriteria<X> withInternal(String name, AbstractQuery<X> criteria) {
|
||||||
|
if ( !( criteria instanceof SqmSubQuery<?> ) || ( (SqmSubQuery<X>) criteria ).getParent() != parent ) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid query type provided to subquery 'with' method, " +
|
||||||
|
"expecting a subquery with the same parent to use as CTE"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return super.withInternal( name, criteria );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected <X> JpaCteCriteria<X> withInternal(
|
||||||
|
String name,
|
||||||
|
AbstractQuery<X> baseCriteria,
|
||||||
|
boolean unionDistinct,
|
||||||
|
Function<JpaCteCriteria<X>, AbstractQuery<X>> recursiveCriteriaProducer) {
|
||||||
|
if ( !( baseCriteria instanceof SqmSubQuery<?> ) || ( (SqmSubQuery<X>) baseCriteria ).getParent() != parent ) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid query type provided to subquery 'with' method, " +
|
||||||
|
"expecting a subquery with the same parent to use as CTE"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return super.withInternal( name, baseCriteria, unionDistinct, recursiveCriteriaProducer );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmQuery<?> getContainingQuery() {
|
public SqmQuery<?> getContainingQuery() {
|
||||||
return parent;
|
return parent;
|
||||||
|
|
Loading…
Reference in New Issue