use of org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate in project hibernate-orm by hibernate.
the class UpdateExecutionDelegate method updateTable.
private void updateTable(String tableExpression, Supplier<Consumer<SelectableConsumer>> tableKeyColumnVisitationSupplier, QuerySpec idTableSubQuery, ExecutionContext executionContext) {
final TableReference updatingTableReference = updatingTableGroup.getTableReference(updatingTableGroup.getNavigablePath(), tableExpression, true, true);
final List<Assignment> assignments = assignmentsByTable.get(updatingTableReference);
if (assignments == null || assignments.isEmpty()) {
// no assignments for this table - skip it
return;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// create the in-subquery predicate to restrict the updates to just
// matching ids
final TableKeyExpressionCollector keyColumnCollector = new TableKeyExpressionCollector(entityDescriptor);
tableKeyColumnVisitationSupplier.get().accept((columnIndex, selection) -> {
assert selection.getContainingTableExpression().equals(tableExpression);
keyColumnCollector.apply(new ColumnReference((String) null, selection, sessionFactory));
});
final InSubQueryPredicate idTableSubQueryPredicate = new InSubQueryPredicate(keyColumnCollector.buildKeyExpression(), idTableSubQuery, false);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Create the SQL AST and convert it into a JdbcOperation
final UpdateStatement sqlAst = new UpdateStatement(resolveUnionTableReference(updatingTableReference, tableExpression), assignments, idTableSubQueryPredicate);
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
final JdbcUpdate jdbcUpdate = jdbcServices.getJdbcEnvironment().getSqlAstTranslatorFactory().buildUpdateTranslator(sessionFactory, sqlAst).translate(jdbcParameterBindings, executionContext.getQueryOptions());
jdbcServices.getJdbcMutationExecutor().execute(jdbcUpdate, jdbcParameterBindings, sql -> executionContext.getSession().getJdbcCoordinator().getStatementPreparer().prepareStatement(sql), (integer, preparedStatement) -> {
}, executionContext);
}
use of org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate in project hibernate-orm by hibernate.
the class RestrictedDeleteExecutionDelegate method deleteFromNonRootTableWithoutIdTable.
private int deleteFromNonRootTableWithoutIdTable(NamedTableReference targetTableReference, Supplier<Consumer<SelectableConsumer>> tableKeyColumnVisitationSupplier, SqlExpressionResolver sqlExpressionResolver, TableGroup rootTableGroup, QuerySpec matchingIdSubQuerySpec, JdbcParameterBindings jdbcParameterBindings, ExecutionContext executionContext) {
assert targetTableReference != null;
log.tracef("deleteFromNonRootTable - %s", targetTableReference.getTableExpression());
final NamedTableReference deleteTableReference = new NamedTableReference(targetTableReference.getTableExpression(), DeleteStatement.DEFAULT_ALIAS, true, sessionFactory);
final Predicate tableDeletePredicate;
if (matchingIdSubQuerySpec == null) {
tableDeletePredicate = null;
} else {
/*
* delete from sub_table
* where sub_id in (
* select root_id from root_table
* where {predicate}
* )
*/
/*
* Create the `sub_id` reference as the LHS of the in-subquery predicate
*/
final List<ColumnReference> deletingTableColumnRefs = new ArrayList<>();
tableKeyColumnVisitationSupplier.get().accept((columnIndex, selection) -> {
assert deleteTableReference.getTableReference(selection.getContainingTableExpression()) != null;
final Expression expression = sqlExpressionResolver.resolveSqlExpression(SqlExpressionResolver.createColumnReferenceKey(deleteTableReference, selection.getSelectionExpression()), sqlAstProcessingState -> new ColumnReference(deleteTableReference, selection, sessionFactory));
deletingTableColumnRefs.add((ColumnReference) expression);
});
final Expression deletingTableColumnRefsExpression;
if (deletingTableColumnRefs.size() == 1) {
deletingTableColumnRefsExpression = deletingTableColumnRefs.get(0);
} else {
deletingTableColumnRefsExpression = new SqlTuple(deletingTableColumnRefs, entityDescriptor.getIdentifierMapping());
}
tableDeletePredicate = new InSubQueryPredicate(deletingTableColumnRefsExpression, matchingIdSubQuerySpec, false);
}
final DeleteStatement sqlAstDelete = new DeleteStatement(deleteTableReference, tableDeletePredicate);
final int rows = executeSqlDelete(sqlAstDelete, jdbcParameterBindings, executionContext);
log.debugf("deleteFromNonRootTable - `%s` : %s rows", targetTableReference, rows);
return rows;
}
use of org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate in project hibernate-orm by hibernate.
the class RestrictedDeleteExecutionDelegate method deleteFromTableUsingIdTable.
private void deleteFromTableUsingIdTable(String tableExpression, Supplier<Consumer<SelectableConsumer>> tableKeyColumnVisitationSupplier, QuerySpec idTableSubQuery, ExecutionContext executionContext) {
log.tracef("deleteFromTableUsingIdTable - %s", tableExpression);
final SessionFactoryImplementor factory = executionContext.getSession().getFactory();
final TableKeyExpressionCollector keyColumnCollector = new TableKeyExpressionCollector(entityDescriptor);
final NamedTableReference targetTable = new NamedTableReference(tableExpression, DeleteStatement.DEFAULT_ALIAS, true, factory);
tableKeyColumnVisitationSupplier.get().accept((columnIndex, selection) -> {
assert selection.getContainingTableExpression().equals(tableExpression);
assert !selection.isFormula();
assert selection.getCustomReadExpression() == null;
assert selection.getCustomWriteExpression() == null;
keyColumnCollector.apply(new ColumnReference(targetTable, selection, factory));
});
final InSubQueryPredicate predicate = new InSubQueryPredicate(keyColumnCollector.buildKeyExpression(), idTableSubQuery, false);
executeSqlDelete(new DeleteStatement(targetTable, predicate), JdbcParameterBindings.NO_BINDINGS, executionContext);
}
use of org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate in project hibernate-orm by hibernate.
the class ExpressionReplacementWalker method visitInSubQueryPredicate.
@Override
public void visitInSubQueryPredicate(InSubQueryPredicate inSubQueryPredicate) {
final Expression testExpression = replaceExpression(inSubQueryPredicate.getTestExpression());
final QueryPart subQuery = replaceExpression(inSubQueryPredicate.getSubQuery());
if (testExpression != inSubQueryPredicate.getTestExpression() || subQuery != inSubQueryPredicate.getSubQuery()) {
returnedNode = new InSubQueryPredicate(testExpression, subQuery, inSubQueryPredicate.isNegated(), inSubQueryPredicate.getExpressionType());
} else {
returnedNode = inSubQueryPredicate;
}
}
use of org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate in project hibernate-orm by hibernate.
the class LoaderSelectBuilder method applySubSelectRestriction.
private void applySubSelectRestriction(QuerySpec querySpec, NavigablePath rootNavigablePath, TableGroup rootTableGroup, SubselectFetch subselect, LoaderSqlAstCreationState sqlAstCreationState) {
final SqlAstCreationContext sqlAstCreationContext = sqlAstCreationState.getCreationContext();
final SessionFactoryImplementor sessionFactory = sqlAstCreationContext.getSessionFactory();
assert loadable instanceof PluralAttributeMapping;
final PluralAttributeMapping attributeMapping = (PluralAttributeMapping) loadable;
final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor();
final NavigablePath navigablePath = rootNavigablePath.append(attributeMapping.getAttributeName());
final Expression fkExpression;
final int jdbcTypeCount = fkDescriptor.getJdbcTypeCount();
if (jdbcTypeCount == 1) {
assert fkDescriptor instanceof SimpleForeignKeyDescriptor;
final SimpleForeignKeyDescriptor simpleFkDescriptor = (SimpleForeignKeyDescriptor) fkDescriptor;
final TableReference tableReference = rootTableGroup.resolveTableReference(navigablePath, simpleFkDescriptor.getContainingTableExpression());
fkExpression = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(createColumnReferenceKey(tableReference, simpleFkDescriptor.getSelectionExpression()), sqlAstProcessingState -> new ColumnReference(tableReference, simpleFkDescriptor.getSelectionExpression(), false, null, null, simpleFkDescriptor.getJdbcMapping(), this.creationContext.getSessionFactory()));
} else {
final List<ColumnReference> columnReferences = new ArrayList<>(jdbcTypeCount);
fkDescriptor.forEachSelectable((columnIndex, selection) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference(navigablePath, selection.getContainingTableExpression());
columnReferences.add((ColumnReference) sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(createColumnReferenceKey(tableReference, selection.getSelectionExpression()), sqlAstProcessingState -> new ColumnReference(tableReference, selection, this.creationContext.getSessionFactory())));
});
fkExpression = new SqlTuple(columnReferences, fkDescriptor);
}
querySpec.applyPredicate(new InSubQueryPredicate(fkExpression, generateSubSelect(attributeMapping, rootTableGroup, subselect, jdbcTypeCount, sqlAstCreationState, sessionFactory), false));
}
Aggregations