use of org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate in project hibernate-orm by hibernate.
the class AbstractCteMutationHandler method createIdSubQueryPredicate.
protected Predicate createIdSubQueryPredicate(List<? extends Expression> lhsExpressions, CteStatement idSelectCte, ModelPart fkModelPart, SessionFactoryImplementor factory) {
final NamedTableReference idSelectTableReference = new NamedTableReference(idSelectCte.getCteTable().getTableExpression(), CTE_TABLE_IDENTIFIER, false, factory);
final Junction predicate = new Junction(Junction.Nature.CONJUNCTION);
final List<CteColumn> cteColumns = idSelectCte.getCteTable().getCteColumns();
final int size = lhsExpressions.size();
final QuerySpec subQuery = new QuerySpec(false, 1);
subQuery.getFromClause().addRoot(new CteTableGroup(idSelectTableReference));
final SelectClause subQuerySelectClause = subQuery.getSelectClause();
if (fkModelPart == null) {
for (int i = 0; i < size; i++) {
final CteColumn cteColumn = cteColumns.get(i);
subQuerySelectClause.addSqlSelection(new SqlSelectionImpl(i + 1, i, new ColumnReference(idSelectTableReference, cteColumn.getColumnExpression(), cteColumn.getJdbcMapping(), factory)));
}
} else {
fkModelPart.forEachSelectable((selectionIndex, selectableMapping) -> {
subQuerySelectClause.addSqlSelection(new SqlSelectionImpl(selectionIndex + 1, selectionIndex, new ColumnReference(idSelectTableReference, selectableMapping.getSelectionExpression(), selectableMapping.getJdbcMapping(), factory)));
});
}
final Expression lhs;
if (lhsExpressions.size() == 1) {
lhs = lhsExpressions.get(0);
} else {
lhs = new SqlTuple(lhsExpressions, null);
}
predicate.add(new InSubQueryPredicate(lhs, subQuery, false));
return predicate;
}
use of org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate in project hibernate-orm by hibernate.
the class SimpleDeleteQueryPlan method executeUpdate.
@Override
public int executeUpdate(DomainQueryExecutionContext executionContext) {
BulkOperationCleanupAction.schedule(executionContext.getSession(), sqmDelete);
final SharedSessionContractImplementor session = executionContext.getSession();
final SessionFactoryImplementor factory = session.getFactory();
final JdbcServices jdbcServices = factory.getJdbcServices();
SqlAstTranslator<JdbcDelete> deleteTranslator = null;
if (jdbcDelete == null) {
deleteTranslator = createDeleteTranslator(executionContext);
}
final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(executionContext.getQueryParameterBindings(), domainParameterXref, jdbcParamsXref, factory.getRuntimeMetamodels().getMappingMetamodel(), sqmInterpretation.getFromClauseAccess()::findTableGroup, new SqmParameterMappingModelResolutionAccess() {
@Override
@SuppressWarnings("unchecked")
public <T> MappingModelExpressible<T> getResolvedMappingModelType(SqmParameter<T> parameter) {
return (MappingModelExpressible<T>) sqmInterpretation.getSqmParameterMappingModelTypeResolutions().get(parameter);
}
}, session);
if (jdbcDelete != null && !jdbcDelete.isCompatibleWith(jdbcParameterBindings, executionContext.getQueryOptions())) {
deleteTranslator = createDeleteTranslator(executionContext);
}
if (deleteTranslator != null) {
jdbcDelete = deleteTranslator.translate(jdbcParameterBindings, executionContext.getQueryOptions());
} else {
jdbcDelete.bindFilterJdbcParameters(jdbcParameterBindings);
}
final boolean missingRestriction = sqmDelete.getWhereClause() == null || sqmDelete.getWhereClause().getPredicate() == null;
if (missingRestriction) {
assert domainParameterXref.getSqmParameterCount() == 0;
assert jdbcParamsXref.isEmpty();
}
final SqmJdbcExecutionContextAdapter executionContextAdapter = SqmJdbcExecutionContextAdapter.usingLockingAndPaging(executionContext);
SqmMutationStrategyHelper.cleanUpCollectionTables(entityDescriptor, (tableReference, attributeMapping) -> {
if (missingRestriction) {
return null;
}
final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor();
final Expression fkColumnExpression = MappingModelHelper.buildColumnReferenceExpression(fkDescriptor.getKeyPart(), null, factory);
final QuerySpec matchingIdSubQuery = new QuerySpec(false);
final MutatingTableReferenceGroupWrapper tableGroup = new MutatingTableReferenceGroupWrapper(new NavigablePath(attributeMapping.getRootPathName()), attributeMapping, sqmInterpretation.getSqlAst().getTargetTable());
final Expression fkTargetColumnExpression = MappingModelHelper.buildColumnReferenceExpression(tableGroup, fkDescriptor.getTargetPart(), sqmInterpretation.getSqlExpressionResolver(), factory);
matchingIdSubQuery.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, fkTargetColumnExpression));
matchingIdSubQuery.getFromClause().addRoot(tableGroup);
matchingIdSubQuery.applyPredicate(sqmInterpretation.getSqlAst().getRestriction());
return new InSubQueryPredicate(fkColumnExpression, matchingIdSubQuery, false);
}, (missingRestriction ? JdbcParameterBindings.NO_BINDINGS : jdbcParameterBindings), executionContextAdapter);
return jdbcServices.getJdbcMutationExecutor().execute(jdbcDelete, jdbcParameterBindings, sql -> session.getJdbcCoordinator().getStatementPreparer().prepareStatement(sql), (integer, preparedStatement) -> {
}, executionContextAdapter);
}
use of org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitMemberOfPredicate.
@Override
public Predicate visitMemberOfPredicate(SqmMemberOfPredicate predicate) {
final SqmPath<?> pluralPath = predicate.getPluralPath();
prepareReusablePath(pluralPath, () -> null);
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) determineValueMapping(pluralPath);
if (pluralAttributeMapping.getElementDescriptor() instanceof EntityCollectionPart) {
inferrableTypeAccessStack.push(() -> ((EntityCollectionPart) pluralAttributeMapping.getElementDescriptor()).getKeyTargetMatchPart());
} else if (pluralAttributeMapping.getElementDescriptor() instanceof EmbeddedCollectionPart) {
inferrableTypeAccessStack.push(pluralAttributeMapping::getElementDescriptor);
} else {
inferrableTypeAccessStack.push(() -> pluralAttributeMapping);
}
final Expression lhs;
try {
lhs = (Expression) predicate.getLeftHandExpression().accept(this);
} finally {
inferrableTypeAccessStack.pop();
}
final FromClauseAccess parentFromClauseAccess = getFromClauseAccess();
final QuerySpec subQuerySpec = new QuerySpec(false);
pushProcessingState(new SqlAstQueryPartProcessingStateImpl(subQuerySpec, getCurrentProcessingState(), this, currentClauseStack::getCurrent, false));
try {
final TableGroup tableGroup = pluralAttributeMapping.createRootTableGroup(true, pluralPath.getNavigablePath(), null, () -> subQuerySpec::applyPredicate, this, creationContext);
pluralAttributeMapping.applyBaseRestrictions(subQuerySpec::applyPredicate, tableGroup, true, getLoadQueryInfluencers().getEnabledFilters(), null, this);
getFromClauseAccess().registerTableGroup(pluralPath.getNavigablePath(), tableGroup);
registerPluralTableGroupParts(tableGroup);
subQuerySpec.getFromClause().addRoot(tableGroup);
final CollectionPart elementDescriptor = pluralAttributeMapping.getElementDescriptor();
if (elementDescriptor instanceof EntityCollectionPart) {
((EntityCollectionPart) elementDescriptor).getKeyTargetMatchPart().createDomainResult(pluralPath.getNavigablePath(), tableGroup, null, this);
} else {
elementDescriptor.createDomainResult(pluralPath.getNavigablePath(), tableGroup, null, this);
}
subQuerySpec.applyPredicate(pluralAttributeMapping.getKeyDescriptor().generateJoinPredicate(parentFromClauseAccess.findTableGroup(pluralPath.getNavigablePath().getParent()), tableGroup, getSqlExpressionResolver(), creationContext));
} finally {
popProcessingStateStack();
}
return new InSubQueryPredicate(lhs, subQuerySpec, predicate.isNegated(), getBooleanType());
}
use of org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate in project hibernate-orm by hibernate.
the class RestrictedDeleteExecutionDelegate method executeWithoutIdTable.
private int executeWithoutIdTable(Predicate suppliedPredicate, TableGroup tableGroup, Map<SqmParameter<?>, List<List<JdbcParameter>>> restrictionSqmParameterResolutions, Map<SqmParameter<?>, MappingModelExpressible<?>> paramTypeResolutions, SqlExpressionResolver sqlExpressionResolver, ExecutionContext executionContext) {
assert entityDescriptor == entityDescriptor.getRootEntityDescriptor();
final EntityPersister rootEntityPersister = entityDescriptor.getEntityPersister();
final String rootTableName = ((Joinable) rootEntityPersister).getTableName();
final NamedTableReference rootTableReference = (NamedTableReference) tableGroup.resolveTableReference(tableGroup.getNavigablePath(), rootTableName);
final QuerySpec matchingIdSubQuerySpec = ExecuteWithoutIdTableHelper.createIdMatchingSubQuerySpec(tableGroup.getNavigablePath(), rootTableReference, suppliedPredicate, rootEntityPersister, sqlExpressionResolver, sessionFactory);
final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(executionContext.getQueryParameterBindings(), domainParameterXref, SqmUtil.generateJdbcParamsXref(domainParameterXref, () -> restrictionSqmParameterResolutions), sessionFactory.getRuntimeMetamodels().getMappingMetamodel(), navigablePath -> tableGroup, new SqmParameterMappingModelResolutionAccess() {
@Override
@SuppressWarnings("unchecked")
public <T> MappingModelExpressible<T> getResolvedMappingModelType(SqmParameter<T> parameter) {
return (MappingModelExpressible<T>) paramTypeResolutions.get(parameter);
}
}, executionContext.getSession());
SqmMutationStrategyHelper.cleanUpCollectionTables(entityDescriptor, (tableReference, attributeMapping) -> {
// No need for a predicate if there is no supplied predicate i.e. this is a full cleanup
if (suppliedPredicate == null) {
return null;
}
final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor();
final QuerySpec idSelectFkSubQuery;
// todo (6.0): based on the location of the attribute mapping, we could prune the table group of the subquery
if (fkDescriptor.getTargetPart() instanceof EntityIdentifierMapping) {
idSelectFkSubQuery = matchingIdSubQuerySpec;
} else {
idSelectFkSubQuery = ExecuteWithoutIdTableHelper.createIdMatchingSubQuerySpec(tableGroup.getNavigablePath(), rootTableReference, suppliedPredicate, rootEntityPersister, sqlExpressionResolver, sessionFactory);
}
return new InSubQueryPredicate(MappingModelHelper.buildColumnReferenceExpression(fkDescriptor, null, sessionFactory), idSelectFkSubQuery, false);
}, jdbcParameterBindings, executionContext);
if (rootTableReference instanceof UnionTableReference) {
final MutableInteger rows = new MutableInteger();
entityDescriptor.visitConstraintOrderedTables((tableExpression, tableKeyColumnVisitationSupplier) -> {
final NamedTableReference tableReference = new NamedTableReference(tableExpression, tableGroup.getPrimaryTableReference().getIdentificationVariable(), false, sessionFactory);
final QuerySpec idMatchingSubQuerySpec;
// No need for a predicate if there is no supplied predicate i.e. this is a full cleanup
if (suppliedPredicate == null) {
idMatchingSubQuerySpec = null;
} else {
idMatchingSubQuerySpec = matchingIdSubQuerySpec;
}
rows.plus(deleteFromNonRootTableWithoutIdTable(tableReference, tableKeyColumnVisitationSupplier, sqlExpressionResolver, tableGroup, idMatchingSubQuerySpec, jdbcParameterBindings, executionContext));
});
return rows.get();
} else {
entityDescriptor.visitConstraintOrderedTables((tableExpression, tableKeyColumnVisitationSupplier) -> {
if (!tableExpression.equals(rootTableName)) {
final NamedTableReference tableReference = (NamedTableReference) tableGroup.getTableReference(tableGroup.getNavigablePath(), tableExpression, true, true);
final QuerySpec idMatchingSubQuerySpec;
// No need for a predicate if there is no supplied predicate i.e. this is a full cleanup
if (suppliedPredicate == null) {
idMatchingSubQuerySpec = null;
} else {
idMatchingSubQuerySpec = matchingIdSubQuerySpec;
}
deleteFromNonRootTableWithoutIdTable(tableReference, tableKeyColumnVisitationSupplier, sqlExpressionResolver, tableGroup, idMatchingSubQuerySpec, jdbcParameterBindings, executionContext);
}
});
return deleteFromRootTableWithoutIdTable(rootTableReference, suppliedPredicate, jdbcParameterBindings, executionContext);
}
}
use of org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate in project hibernate-orm by hibernate.
the class RestrictedDeleteExecutionDelegate method executeUsingIdTable.
private int executeUsingIdTable(Predicate predicate, ExecutionContext executionContext, JdbcParameterBindings jdbcParameterBindings) {
final int rows = ExecuteWithTemporaryTableHelper.saveMatchingIdsIntoIdTable(converter, predicate, idTable, sessionUidAccess, jdbcParameterBindings, executionContext);
final QuerySpec idTableIdentifierSubQuery = ExecuteWithTemporaryTableHelper.createIdTableSelectQuerySpec(idTable, sessionUidAccess, entityDescriptor, executionContext);
SqmMutationStrategyHelper.cleanUpCollectionTables(entityDescriptor, (tableReference, attributeMapping) -> {
final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor();
final QuerySpec idTableFkSubQuery;
if (fkDescriptor.getTargetPart() instanceof EntityIdentifierMapping) {
idTableFkSubQuery = idTableIdentifierSubQuery;
} else {
idTableFkSubQuery = ExecuteWithTemporaryTableHelper.createIdTableSelectQuerySpec(idTable, fkDescriptor.getTargetPart(), sessionUidAccess, entityDescriptor, executionContext);
}
return new InSubQueryPredicate(MappingModelHelper.buildColumnReferenceExpression(fkDescriptor, null, sessionFactory), idTableFkSubQuery, false);
}, JdbcParameterBindings.NO_BINDINGS, executionContext);
entityDescriptor.visitConstraintOrderedTables((tableExpression, tableKeyColumnVisitationSupplier) -> deleteFromTableUsingIdTable(tableExpression, tableKeyColumnVisitationSupplier, idTableIdentifierSubQuery, executionContext));
return rows;
}
Aggregations