use of org.hibernate.sql.ast.tree.predicate.Predicate in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitInListPredicate.
@Override
public Predicate visitInListPredicate(SqmInListPredicate<?> predicate) {
// handling for "expansion"
if (predicate.getListExpressions().size() == 1) {
final SqmExpression<?> sqmExpression = predicate.getListExpressions().get(0);
if (sqmExpression instanceof SqmParameter) {
final SqmParameter<?> sqmParameter = (SqmParameter<?>) sqmExpression;
if (sqmParameter.allowMultiValuedBinding()) {
final Predicate specialCase = processInListWithSingleParameter(predicate, sqmParameter);
if (specialCase != null) {
return specialCase;
}
}
}
}
// otherwise - no special case...
final FromClauseIndex fromClauseIndex = fromClauseIndexStack.getCurrent();
inferrableTypeAccessStack.push(() -> {
for (SqmExpression<?> listExpression : predicate.getListExpressions()) {
final MappingModelExpressible<?> mapping = determineValueMapping(listExpression, fromClauseIndex);
if (mapping != null) {
return mapping;
}
}
return null;
});
final Expression testExpression;
try {
testExpression = (Expression) predicate.getTestExpression().accept(this);
} finally {
inferrableTypeAccessStack.pop();
}
final InListPredicate inPredicate = new InListPredicate(testExpression, predicate.isNegated(), getBooleanType());
inferrableTypeAccessStack.push(() -> determineValueMapping(predicate.getTestExpression(), fromClauseIndex));
try {
for (SqmExpression<?> expression : predicate.getListExpressions()) {
inPredicate.addExpression((Expression) expression.accept(this));
}
} finally {
inferrableTypeAccessStack.pop();
}
return inPredicate;
}
use of org.hibernate.sql.ast.tree.predicate.Predicate in project hibernate-orm by hibernate.
the class RestrictedDeleteExecutionDelegate method execute.
@Override
public int execute(DomainQueryExecutionContext executionContext) {
final EntityPersister entityDescriptor = sessionFactory.getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor(sqmDelete.getTarget().getEntityName());
final String hierarchyRootTableName = ((Joinable) entityDescriptor).getTableName();
final TableGroup deletingTableGroup = converter.getMutatingTableGroup();
final TableReference hierarchyRootTableReference = deletingTableGroup.resolveTableReference(deletingTableGroup.getNavigablePath(), hierarchyRootTableName);
assert hierarchyRootTableReference != null;
final Map<SqmParameter<?>, List<List<JdbcParameter>>> parameterResolutions;
final Map<SqmParameter<?>, MappingModelExpressible<?>> paramTypeResolutions;
if (domainParameterXref.getSqmParameterCount() == 0) {
parameterResolutions = Collections.emptyMap();
paramTypeResolutions = Collections.emptyMap();
} else {
parameterResolutions = new IdentityHashMap<>();
paramTypeResolutions = new LinkedHashMap<>();
}
// Use the converter to interpret the where-clause. We do this for 2 reasons:
// 1) the resolved Predicate is ultimately the base for applying restriction to the deletes
// 2) we also inspect each ColumnReference that is part of the where-clause to see which
// table it comes from. if all of the referenced columns (if any at all) are from the root table
// we can perform all of the deletes without using an id-table
final MutableBoolean needsIdTableWrapper = new MutableBoolean(false);
final Predicate specifiedRestriction = converter.visitWhereClause(sqmDelete.getWhereClause(), columnReference -> {
if (!hierarchyRootTableReference.getIdentificationVariable().equals(columnReference.getQualifier())) {
needsIdTableWrapper.setValue(true);
}
}, (sqmParameter, mappingType, jdbcParameters) -> {
parameterResolutions.computeIfAbsent(sqmParameter, k -> new ArrayList<>(1)).add(jdbcParameters);
paramTypeResolutions.put(sqmParameter, mappingType);
});
final PredicateCollector predicateCollector = new PredicateCollector(specifiedRestriction);
entityDescriptor.applyBaseRestrictions((filterPredicate) -> {
needsIdTableWrapper.setValue(true);
predicateCollector.applyPredicate(filterPredicate);
}, deletingTableGroup, true, executionContext.getSession().getLoadQueryInfluencers().getEnabledFilters(), null, converter);
converter.pruneTableGroupJoins();
// We need an id table if we want to delete from an intermediate table to avoid FK violations
// The intermediate table has a FK to the root table, so we can't delete from the root table first
// Deleting from the intermediate table first also isn't possible,
// because that is the source for deletion in other tables, hence we need an id table
final boolean needsIdTable = needsIdTableWrapper.getValue() || entityDescriptor != entityDescriptor.getRootEntityDescriptor();
final SqmJdbcExecutionContextAdapter executionContextAdapter = SqmJdbcExecutionContextAdapter.omittingLockingAndPaging(executionContext);
if (needsIdTable) {
return executeWithIdTable(predicateCollector.getPredicate(), deletingTableGroup, parameterResolutions, paramTypeResolutions, executionContextAdapter);
} else {
return executeWithoutIdTable(predicateCollector.getPredicate(), deletingTableGroup, parameterResolutions, paramTypeResolutions, converter.getSqlExpressionResolver(), executionContextAdapter);
}
}
use of org.hibernate.sql.ast.tree.predicate.Predicate 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.sql.ast.tree.predicate.Predicate in project hibernate-orm by hibernate.
the class SQLServerSqlAstTranslator method renderTableGroupJoin.
@Override
protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List<TableGroupJoin> tableGroupJoinCollector) {
appendSql(WHITESPACE);
if (tableGroupJoin.getJoinedGroup().isLateral()) {
if (tableGroupJoin.getJoinType() == SqlAstJoinType.LEFT) {
appendSql("outer apply ");
} else {
appendSql("cross apply ");
}
} else {
appendSql(tableGroupJoin.getJoinType().getText());
appendSql("join ");
}
final Predicate predicate = tableGroupJoin.getPredicate();
if (predicate != null && !predicate.isEmpty()) {
if (tableGroupJoin.getJoinedGroup().isLateral()) {
// We have to inject the lateral predicate into the sub-query
final Predicate lateralPredicate = this.lateralPredicate;
this.lateralPredicate = predicate;
renderTableGroup(tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector);
this.lateralPredicate = lateralPredicate;
} else {
renderTableGroup(tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector);
}
} else {
renderTableGroup(tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector);
}
}
use of org.hibernate.sql.ast.tree.predicate.Predicate in project hibernate-orm by hibernate.
the class TimesTenSqlAstTranslator method renderTableGroupJoin.
@Override
protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List<TableGroupJoin> tableGroupJoinCollector) {
if (tableGroupJoin.getJoinType() == SqlAstJoinType.CROSS) {
appendSql(", ");
} else {
appendSql(WHITESPACE);
appendSql(tableGroupJoin.getJoinType().getText());
appendSql("join ");
}
final Predicate predicate;
if (tableGroupJoin.getPredicate() == null) {
if (tableGroupJoin.getJoinType() == SqlAstJoinType.CROSS) {
predicate = null;
} else {
predicate = new BooleanExpressionPredicate(new QueryLiteral<>(true, getBooleanType()));
}
} else {
predicate = tableGroupJoin.getPredicate();
}
if (predicate != null && !predicate.isEmpty()) {
renderTableGroup(tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector);
} else {
renderTableGroup(tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector);
}
}
Aggregations