use of org.hibernate.query.sqm.tree.select.SqmSelectQuery in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitSetQueryGroup.
@Override
public SqmQueryGroup<Object> visitSetQueryGroup(HqlParser.SetQueryGroupContext ctx) {
if (creationOptions.useStrictJpaCompliance()) {
throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.SET_OPERATIONS);
}
final List<ParseTree> children = ctx.children;
// noinspection unchecked
final SqmQueryPart<Object> firstQueryPart = (SqmQueryPart<Object>) children.get(0).accept(this);
SqmQueryGroup<Object> queryGroup;
if (firstQueryPart instanceof SqmQueryGroup<?>) {
queryGroup = (SqmQueryGroup<Object>) firstQueryPart;
} else {
queryGroup = new SqmQueryGroup<>(firstQueryPart);
}
setCurrentQueryPart(queryGroup);
final int size = children.size();
final SqmCreationProcessingState firstProcessingState = processingStateStack.pop();
for (int i = 1; i < size; i += 2) {
final SetOperator operator = visitSetOperator((HqlParser.SetOperatorContext) children.get(i));
final HqlParser.OrderedQueryContext simpleQueryCtx = (HqlParser.OrderedQueryContext) children.get(i + 1);
final List<SqmQueryPart<Object>> queryParts;
if (queryGroup.getSetOperator() == null || queryGroup.getSetOperator() == operator) {
queryGroup.setSetOperator(operator);
queryParts = queryGroup.queryParts();
} else {
queryParts = new ArrayList<>(size - (i >> 1));
queryParts.add(queryGroup);
queryGroup = new SqmQueryGroup<>(creationContext.getNodeBuilder(), operator, queryParts);
setCurrentQueryPart(queryGroup);
}
final SqmQueryPart<Object> queryPart;
try {
processingStateStack.push(new SqmQuerySpecCreationProcessingStateStandardImpl(processingStateStack.getCurrent(), (SqmSelectQuery<?>) firstProcessingState.getProcessingQuery(), this));
final List<ParseTree> subChildren = simpleQueryCtx.children;
if (subChildren.get(0) instanceof HqlParser.QueryContext) {
final SqmQuerySpec<Object> querySpec = new SqmQuerySpec<>(creationContext.getNodeBuilder());
queryParts.add(querySpec);
visitQuerySpecExpression((HqlParser.QuerySpecExpressionContext) simpleQueryCtx);
} else {
try {
final SqmSelectStatement<Object> selectStatement = new SqmSelectStatement<>(creationContext.getNodeBuilder());
processingStateStack.push(new SqmQuerySpecCreationProcessingStateStandardImpl(processingStateStack.getCurrent(), selectStatement, this));
queryPart = visitNestedQueryExpression((HqlParser.NestedQueryExpressionContext) simpleQueryCtx);
queryParts.add(queryPart);
} finally {
processingStateStack.pop();
}
}
} finally {
processingStateStack.pop();
}
}
processingStateStack.push(firstProcessingState);
return queryGroup;
}
use of org.hibernate.query.sqm.tree.select.SqmSelectQuery in project hibernate-orm by hibernate.
the class QualifiedJoinPredicatePathConsumer method createBasePart.
@Override
protected SemanticPathPart createBasePart() {
return new BaseLocalSequencePart() {
@Override
protected void validateAsRoot(SqmFrom<?, ?> pathRoot) {
final SqmRoot<?> root = pathRoot.findRoot();
final SqmRoot<?> joinRoot = sqmJoin.findRoot();
if (root != joinRoot) {
// The root of a path within a join condition doesn't have the same root as the current join we are processing.
// The aim of this check is to prevent uses of different "spaces" i.e. `from A a, B b join b.id = a.id` would be illegal
SqmCreationProcessingState processingState = getCreationState().getCurrentProcessingState();
// First, we need to find out if the current join is part of current processing query
final SqmQuery<?> currentProcessingQuery = processingState.getProcessingQuery();
if (currentProcessingQuery instanceof SqmSelectQuery<?>) {
final SqmQuerySpec<?> querySpec = ((SqmSelectQuery<?>) currentProcessingQuery).getQuerySpec();
final SqmFromClause fromClause = querySpec.getFromClause();
// then the root of the processing path must be a root of one of the parent queries
if (fromClause != null && fromClause.getRoots().contains(joinRoot)) {
// It is allowed to use correlations from the same query
if (!(root instanceof SqmCorrelation<?, ?>) || !fromClause.getRoots().contains(root)) {
validateAsRootOnParentQueryClosure(pathRoot, root, processingState.getParentProcessingState());
}
return;
}
}
// in which case the path root is allowed to occur in the current processing query as root
if (currentProcessingQuery instanceof SqmSubQuery<?>) {
validateAsRootOnParentQueryClosure(pathRoot, root, processingState);
return;
}
throw new SemanticException(String.format(Locale.ROOT, "SqmQualifiedJoin predicate referred to SqmRoot [`%s`] other than the join's root [`%s`]", pathRoot.getNavigablePath().getFullPath(), sqmJoin.getNavigablePath().getFullPath()));
}
super.validateAsRoot(pathRoot);
}
private void validateAsRootOnParentQueryClosure(SqmFrom<?, ?> pathRoot, SqmRoot<?> root, SqmCreationProcessingState processingState) {
while (processingState != null) {
final SqmQuery<?> processingQuery = processingState.getProcessingQuery();
if (processingQuery instanceof SqmSelectQuery<?>) {
final SqmQuerySpec<?> querySpec = ((SqmSelectQuery<?>) processingQuery).getQuerySpec();
final SqmFromClause fromClause = querySpec.getFromClause();
// i.e. `from A a, B b join b.id = a.id` would be illegal
if (fromClause != null && fromClause.getRoots().contains(root)) {
super.validateAsRoot(pathRoot);
return;
}
}
processingState = processingState.getParentProcessingState();
}
throw new SemanticException(String.format(Locale.ROOT, "SqmQualifiedJoin predicate referred to SqmRoot [`%s`] other than the join's root [`%s`]", pathRoot.getNavigablePath().getFullPath(), sqmJoin.getNavigablePath().getFullPath()));
}
};
}
Aggregations