use of org.hibernate.query.sqm.tree.predicate.SqmWhereClause in project hibernate-orm by hibernate.
the class SqmQuerySpec method setRestriction.
@Override
public SqmQuerySpec<T> setRestriction(JpaPredicate restriction) {
SqmWhereClause whereClause = getWhereClause();
if (whereClause == null) {
setWhereClause(whereClause = new SqmWhereClause(nodeBuilder()));
}
whereClause.setPredicate((SqmPredicate) restriction);
return this;
}
use of org.hibernate.query.sqm.tree.predicate.SqmWhereClause in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitQuerySpec.
@Override
public QuerySpec visitQuerySpec(SqmQuerySpec<?> sqmQuerySpec) {
final boolean topLevel = getProcessingStateStack().isEmpty();
final QuerySpec sqlQuerySpec = new QuerySpec(topLevel, sqmQuerySpec.getFromClause().getNumberOfRoots());
final SqmSelectClause selectClause = sqmQuerySpec.getSelectClause();
final Predicate originalAdditionalRestrictions = additionalRestrictions;
additionalRestrictions = null;
final boolean trackAliasedNodePositions;
if (trackSelectionsForGroup) {
trackAliasedNodePositions = true;
} else if (sqmQuerySpec.getOrderByClause() != null && sqmQuerySpec.getOrderByClause().hasPositionalSortItem()) {
trackAliasedNodePositions = true;
} else if (sqmQuerySpec.hasPositionalGroupItem()) {
trackAliasedNodePositions = true;
} else {
// Since JPA Criteria queries can use the same expression object in order or group by items,
// we need to track the positions to be able to replace the expression in the items with alias references
// Also see #resolveGroupOrOrderByExpression for more details
trackAliasedNodePositions = statement.getQuerySource() == SqmQuerySource.CRITERIA && (sqmQuerySpec.getOrderByClause() != null || !sqmQuerySpec.getGroupByClauseExpressions().isEmpty());
}
final SqlAstProcessingState processingState;
if (trackAliasedNodePositions) {
processingState = new SqlAstQueryPartProcessingStateImpl(sqlQuerySpec, getCurrentProcessingState(), this, r -> new SqmAliasedNodePositionTracker(r, selectClause.getSelections()), currentClauseStack::getCurrent, deduplicateSelectionItems);
} else {
processingState = new SqlAstQueryPartProcessingStateImpl(sqlQuerySpec, getCurrentProcessingState(), this, currentClauseStack::getCurrent, deduplicateSelectionItems);
}
final SqmQueryPart<?> sqmQueryPart = currentSqmQueryPart;
final boolean originalDeduplicateSelectionItems = deduplicateSelectionItems;
currentSqmQueryPart = sqmQuerySpec;
// In sub-queries, we can never deduplicate the selection items as that might change semantics
deduplicateSelectionItems = false;
pushProcessingState(processingState);
queryTransformers.push(new ArrayList<>());
try {
// we want to visit the from-clause first
visitFromClause(sqmQuerySpec.getFromClause());
visitSelectClause(selectClause);
final SqmWhereClause whereClause = sqmQuerySpec.getWhereClause();
if (whereClause != null) {
sqlQuerySpec.applyPredicate(visitWhereClause(whereClause.getPredicate()));
}
sqlQuerySpec.setGroupByClauseExpressions(visitGroupByClause(sqmQuerySpec.getGroupByClauseExpressions()));
if (sqmQuerySpec.getHavingClausePredicate() != null) {
sqlQuerySpec.setHavingClauseRestrictions(visitHavingClause(sqmQuerySpec.getHavingClausePredicate()));
}
visitOrderByOffsetAndFetch(sqmQuerySpec, sqlQuerySpec);
if (topLevel && statement instanceof SqmSelectStatement<?>) {
if (orderByFragments != null) {
orderByFragments.forEach(entry -> entry.getKey().apply(sqlQuerySpec, entry.getValue(), this));
orderByFragments = null;
}
applyCollectionFilterPredicates(sqlQuerySpec);
}
QuerySpec finalQuerySpec = sqlQuerySpec;
for (QueryTransformer transformer : queryTransformers.getCurrent()) {
finalQuerySpec = transformer.transform(cteContainer, finalQuerySpec, this);
}
return finalQuerySpec;
} finally {
if (additionalRestrictions != null) {
sqlQuerySpec.applyPredicate(additionalRestrictions);
}
additionalRestrictions = originalAdditionalRestrictions;
popProcessingStateStack();
queryTransformers.pop();
currentSqmQueryPart = sqmQueryPart;
deduplicateSelectionItems = originalDeduplicateSelectionItems;
}
}
use of org.hibernate.query.sqm.tree.predicate.SqmWhereClause in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitDeleteStatement.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Delete statement
@Override
public DeleteStatement visitDeleteStatement(SqmDeleteStatement<?> statement) {
final CteContainer cteContainer = this.visitCteContainer(statement);
final String entityName = statement.getTarget().getEntityName();
final EntityPersister entityDescriptor = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor(entityName);
assert entityDescriptor != null;
pushProcessingState(new SqlAstProcessingStateImpl(getCurrentProcessingState(), this, getCurrentClauseStack()::getCurrent));
try {
final NavigablePath rootPath = statement.getTarget().getNavigablePath();
final TableGroup rootTableGroup = entityDescriptor.createRootTableGroup(true, rootPath, statement.getRoot().getAlias(), () -> predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates(additionalRestrictions, predicate), this, getCreationContext());
getFromClauseAccess().registerTableGroup(rootPath, rootTableGroup);
if (!rootTableGroup.getTableReferenceJoins().isEmpty()) {
throw new HibernateException("Not expecting multiple table references for an SQM DELETE");
}
FilterHelper.applyBaseRestrictions((filterPredicate) -> additionalRestrictions = filterPredicate, entityDescriptor, rootTableGroup, AbstractSqlAstTranslator.rendersTableReferenceAlias(Clause.DELETE), getLoadQueryInfluencers(), this);
Predicate suppliedPredicate = null;
final SqmWhereClause whereClause = statement.getWhereClause();
if (whereClause != null) {
suppliedPredicate = visitWhereClause(whereClause.getPredicate());
}
return new DeleteStatement(cteContainer, (NamedTableReference) rootTableGroup.getPrimaryTableReference(), SqlAstTreeHelper.combinePredicates(suppliedPredicate, additionalRestrictions), Collections.emptyList());
} finally {
popProcessingStateStack();
}
}
use of org.hibernate.query.sqm.tree.predicate.SqmWhereClause in project hibernate-orm by hibernate.
the class TableBasedUpdateHandler method resolveDelegate.
private ExecutionDelegate resolveDelegate(DomainQueryExecutionContext executionContext) {
final SessionFactoryImplementor sessionFactory = getSessionFactory();
final MappingMetamodel domainModel = sessionFactory.getRuntimeMetamodels().getMappingMetamodel();
final EntityPersister entityDescriptor = domainModel.getEntityDescriptor(getSqmDeleteOrUpdateStatement().getTarget().getEntityName());
final String rootEntityName = entityDescriptor.getRootEntityName();
final EntityPersister rootEntityDescriptor = domainModel.getEntityDescriptor(rootEntityName);
final String hierarchyRootTableName = ((Joinable) rootEntityDescriptor).getTableName();
final MultiTableSqmMutationConverter converterDelegate = new MultiTableSqmMutationConverter(entityDescriptor, getSqmDeleteOrUpdateStatement(), getSqmDeleteOrUpdateStatement().getTarget(), domainParameterXref, executionContext.getQueryOptions(), executionContext.getSession().getLoadQueryInfluencers(), executionContext.getQueryParameterBindings(), sessionFactory);
final TableGroup updatingTableGroup = converterDelegate.getMutatingTableGroup();
final TableReference hierarchyRootTableReference = updatingTableGroup.resolveTableReference(updatingTableGroup.getNavigablePath(), hierarchyRootTableName);
assert hierarchyRootTableReference != null;
final Map<SqmParameter<?>, List<List<JdbcParameter>>> parameterResolutions;
if (domainParameterXref.getSqmParameterCount() == 0) {
parameterResolutions = Collections.emptyMap();
} else {
parameterResolutions = new IdentityHashMap<>();
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// visit the set-clause using our special converter, collecting
// information about the assignments
final List<Assignment> assignments = new ArrayList<>();
final Map<SqmParameter<?>, MappingModelExpressible<?>> paramTypeResolutions = new LinkedHashMap<>();
converterDelegate.visitSetClause(getSqmDeleteOrUpdateStatement().getSetClause(), assignments::add, (sqmParameter, mappingType, jdbcParameters) -> {
parameterResolutions.computeIfAbsent(sqmParameter, k -> new ArrayList<>(1)).add(jdbcParameters);
paramTypeResolutions.put(sqmParameter, mappingType);
});
converterDelegate.addVersionedAssignment(assignments::add, getSqmDeleteOrUpdateStatement());
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// visit the where-clause using our special converter, collecting information
// about the restrictions
final Predicate providedPredicate;
final SqmWhereClause whereClause = getSqmUpdate().getWhereClause();
if (whereClause == null || whereClause.getPredicate() == null) {
providedPredicate = null;
} else {
providedPredicate = converterDelegate.visitWhereClause(whereClause, columnReference -> {
}, (sqmParameter, mappingType, jdbcParameters) -> {
parameterResolutions.computeIfAbsent(sqmParameter, k -> new ArrayList<>(1)).add(jdbcParameters);
paramTypeResolutions.put(sqmParameter, mappingType);
});
assert providedPredicate != null;
}
final PredicateCollector predicateCollector = new PredicateCollector(providedPredicate);
entityDescriptor.applyBaseRestrictions(predicateCollector::applyPredicate, updatingTableGroup, true, executionContext.getSession().getLoadQueryInfluencers().getEnabledFilters(), null, converterDelegate);
converterDelegate.pruneTableGroupJoins();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// cross-reference the TableReference by alias. The TableGroup already
// cross-references it by name, bu the ColumnReference only has the alias
final Map<String, TableReference> tableReferenceByAlias = CollectionHelper.mapOfSize(updatingTableGroup.getTableReferenceJoins().size() + 1);
collectTableReference(updatingTableGroup.getPrimaryTableReference(), tableReferenceByAlias::put);
for (int i = 0; i < updatingTableGroup.getTableReferenceJoins().size(); i++) {
collectTableReference(updatingTableGroup.getTableReferenceJoins().get(i), tableReferenceByAlias::put);
}
return new UpdateExecutionDelegate(getSqmUpdate(), converterDelegate, idTable, afterUseAction, sessionUidAccess, domainParameterXref, updatingTableGroup, hierarchyRootTableReference, tableReferenceByAlias, assignments, predicateCollector.getPredicate(), parameterResolutions, paramTypeResolutions, executionContext);
}
use of org.hibernate.query.sqm.tree.predicate.SqmWhereClause in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitQuery.
@Override
public SqmQuerySpec<Object> visitQuery(HqlParser.QueryContext ctx) {
// noinspection unchecked
final SqmQuerySpec<Object> sqmQuerySpec = (SqmQuerySpec<Object>) currentQuerySpec();
final int fromIndex;
if (ctx.getChild(0) instanceof HqlParser.FromClauseContext) {
fromIndex = 0;
} else {
fromIndex = 1;
}
// visit from-clause first!!!
visitFromClause((HqlParser.FromClauseContext) ctx.getChild(fromIndex));
final SqmSelectClause selectClause;
if (fromIndex == 1) {
selectClause = visitSelectClause((HqlParser.SelectClauseContext) ctx.getChild(0));
} else if (ctx.getChild(ctx.getChildCount() - 1) instanceof HqlParser.SelectClauseContext) {
selectClause = visitSelectClause((HqlParser.SelectClauseContext) ctx.getChild(ctx.getChildCount() - 1));
} else {
if (creationOptions.useStrictJpaCompliance()) {
throw new StrictJpaComplianceViolation("Encountered implicit select-clause, but strict JPQL compliance was requested", StrictJpaComplianceViolation.Type.IMPLICIT_SELECT);
}
log.debugf("Encountered implicit select clause : %s", ctx.getText());
selectClause = buildInferredSelectClause(sqmQuerySpec.getFromClause());
}
sqmQuerySpec.setSelectClause(selectClause);
int currentIndex = fromIndex + 1;
final SqmWhereClause whereClause = new SqmWhereClause(creationContext.getNodeBuilder());
if (currentIndex < ctx.getChildCount() && ctx.getChild(currentIndex) instanceof HqlParser.WhereClauseContext) {
whereClause.setPredicate((SqmPredicate) ctx.getChild(currentIndex++).accept(this));
}
sqmQuerySpec.setWhereClause(whereClause);
if (currentIndex < ctx.getChildCount() && ctx.getChild(currentIndex) instanceof HqlParser.GroupByClauseContext) {
sqmQuerySpec.setGroupByClauseExpressions(visitGroupByClause((HqlParser.GroupByClauseContext) ctx.getChild(currentIndex++)));
}
if (currentIndex < ctx.getChildCount() && ctx.getChild(currentIndex) instanceof HqlParser.HavingClauseContext) {
sqmQuerySpec.setHavingClausePredicate(visitHavingClause((HqlParser.HavingClauseContext) ctx.getChild(currentIndex)));
}
return sqmQuerySpec;
}
Aggregations