Search in sources :

Example 6 with MutationStatement

use of org.hibernate.sql.ast.tree.MutationStatement in project hibernate-orm by hibernate.

the class CteDeleteHandler method addDmlCtes.

@Override
protected void addDmlCtes(CteContainer statement, CteStatement idSelectCte, MultiTableSqmMutationConverter sqmConverter, Map<SqmParameter<?>, List<JdbcParameter>> parameterResolutions, SessionFactoryImplementor factory) {
    final TableGroup updatingTableGroup = sqmConverter.getMutatingTableGroup();
    final SelectStatement idSelectStatement = (SelectStatement) idSelectCte.getCteDefinition();
    sqmConverter.getProcessingStateStack().push(new SqlAstQueryPartProcessingStateImpl(idSelectStatement.getQuerySpec(), sqmConverter.getCurrentProcessingState(), sqmConverter.getSqlAstCreationState(), sqmConverter.getCurrentClauseStack()::getCurrent, false));
    getEntityDescriptor().visitSubTypeAttributeMappings(attribute -> {
        if (attribute instanceof PluralAttributeMapping) {
            final PluralAttributeMapping pluralAttribute = (PluralAttributeMapping) attribute;
            if (pluralAttribute.getSeparateCollectionTable() != null) {
                // Ensure that the FK target columns are available
                final boolean useFkTarget = !(pluralAttribute.getKeyDescriptor().getTargetPart() instanceof EntityIdentifierMapping);
                if (useFkTarget) {
                    final TableGroup mutatingTableGroup = sqmConverter.getMutatingTableGroup();
                    pluralAttribute.getKeyDescriptor().getTargetPart().applySqlSelections(mutatingTableGroup.getNavigablePath(), mutatingTableGroup, sqmConverter, (selection, jdbcMapping) -> {
                        idSelectStatement.getDomainResultDescriptors().add(new BasicResult<>(selection.getValuesArrayPosition(), null, jdbcMapping.getJavaTypeDescriptor()));
                    });
                }
                // this collection has a separate collection table, meaning it is one of:
                // 1) element-collection
                // 2) many-to-many
                // 3) one-to many using a dedicated join-table
                // 
                // in all of these cases, we should clean up the matching rows in the
                // collection table
                final String tableExpression = pluralAttribute.getSeparateCollectionTable();
                final CteTable dmlResultCte = new CteTable(getCteTableName(pluralAttribute), idSelectCte.getCteTable().getCteColumns(), factory);
                final NamedTableReference dmlTableReference = new NamedTableReference(tableExpression, DeleteStatement.DEFAULT_ALIAS, true, factory);
                final List<ColumnReference> columnReferences = new ArrayList<>(idSelectCte.getCteTable().getCteColumns().size());
                pluralAttribute.getKeyDescriptor().visitKeySelectables((index, selectable) -> columnReferences.add(new ColumnReference(dmlTableReference, selectable, factory)));
                final MutationStatement dmlStatement = new DeleteStatement(dmlTableReference, createIdSubQueryPredicate(columnReferences, idSelectCte, useFkTarget ? pluralAttribute.getKeyDescriptor().getTargetPart() : null, factory), columnReferences);
                statement.addCteStatement(new CteStatement(dmlResultCte, dmlStatement));
            }
        }
    });
    sqmConverter.getProcessingStateStack().pop();
    getEntityDescriptor().visitConstraintOrderedTables((tableExpression, tableColumnsVisitationSupplier) -> {
        final String cteTableName = getCteTableName(tableExpression);
        if (statement.getCteStatement(cteTableName) != null) {
            // Since secondary tables could appear multiple times, we have to skip duplicates
            return;
        }
        final CteTable dmlResultCte = new CteTable(cteTableName, idSelectCte.getCteTable().getCteColumns(), factory);
        final TableReference updatingTableReference = updatingTableGroup.getTableReference(updatingTableGroup.getNavigablePath(), tableExpression, true, true);
        final NamedTableReference dmlTableReference = resolveUnionTableReference(updatingTableReference, tableExpression);
        final List<ColumnReference> columnReferences = new ArrayList<>(idSelectCte.getCteTable().getCteColumns().size());
        tableColumnsVisitationSupplier.get().accept((index, selectable) -> columnReferences.add(new ColumnReference(dmlTableReference, selectable, factory)));
        final MutationStatement dmlStatement = new DeleteStatement(dmlTableReference, createIdSubQueryPredicate(columnReferences, idSelectCte, factory), columnReferences);
        statement.addCteStatement(new CteStatement(dmlResultCte, dmlStatement));
    });
}
Also used : TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) PluralAttributeMapping(org.hibernate.metamodel.mapping.PluralAttributeMapping) ArrayList(java.util.ArrayList) SqmDeleteStatement(org.hibernate.query.sqm.tree.delete.SqmDeleteStatement) DeleteStatement(org.hibernate.sql.ast.tree.delete.DeleteStatement) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) SqlAstQueryPartProcessingStateImpl(org.hibernate.query.sqm.sql.internal.SqlAstQueryPartProcessingStateImpl) SqmCteTable(org.hibernate.query.sqm.tree.cte.SqmCteTable) CteTable(org.hibernate.sql.ast.tree.cte.CteTable) MutationStatement(org.hibernate.sql.ast.tree.MutationStatement) TableReference(org.hibernate.sql.ast.tree.from.TableReference) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) EntityIdentifierMapping(org.hibernate.metamodel.mapping.EntityIdentifierMapping) CteStatement(org.hibernate.sql.ast.tree.cte.CteStatement) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference)

Example 7 with MutationStatement

use of org.hibernate.sql.ast.tree.MutationStatement in project hibernate-orm by hibernate.

the class AbstractSqlAstTranslator method visitDeleteStatement.

@Override
public void visitDeleteStatement(DeleteStatement statement) {
    MutationStatement oldDmlStatement = dmlStatement;
    dmlStatement = null;
    try {
        visitCteContainer(statement);
        dmlStatement = statement;
        visitDeleteStatementOnly(statement);
    } finally {
        dmlStatement = oldDmlStatement;
    }
}
Also used : MutationStatement(org.hibernate.sql.ast.tree.MutationStatement)

Example 8 with MutationStatement

use of org.hibernate.sql.ast.tree.MutationStatement in project hibernate-orm by hibernate.

the class AbstractSqlAstTranslator method visitInsertStatement.

@Override
public void visitInsertStatement(InsertStatement statement) {
    MutationStatement oldDmlStatement = dmlStatement;
    dmlStatement = null;
    try {
        visitCteContainer(statement);
        visitInsertStatementOnly(statement);
    } finally {
        dmlStatement = oldDmlStatement;
    }
}
Also used : MutationStatement(org.hibernate.sql.ast.tree.MutationStatement)

Aggregations

MutationStatement (org.hibernate.sql.ast.tree.MutationStatement)8 ArrayList (java.util.ArrayList)4 SqmCteTable (org.hibernate.query.sqm.tree.cte.SqmCteTable)4 CteStatement (org.hibernate.sql.ast.tree.cte.CteStatement)4 CteTable (org.hibernate.sql.ast.tree.cte.CteTable)4 ColumnReference (org.hibernate.sql.ast.tree.expression.ColumnReference)4 NamedTableReference (org.hibernate.sql.ast.tree.from.NamedTableReference)4 TableGroup (org.hibernate.sql.ast.tree.from.TableGroup)4 TableReference (org.hibernate.sql.ast.tree.from.TableReference)4 List (java.util.List)2 EntityIdentifierMapping (org.hibernate.metamodel.mapping.EntityIdentifierMapping)2 EntityMappingType (org.hibernate.metamodel.mapping.EntityMappingType)2 PluralAttributeMapping (org.hibernate.metamodel.mapping.PluralAttributeMapping)2 EntityPersister (org.hibernate.persister.entity.EntityPersister)2 Joinable (org.hibernate.persister.entity.Joinable)2 SqlAstQueryPartProcessingStateImpl (org.hibernate.query.sqm.sql.internal.SqlAstQueryPartProcessingStateImpl)2 SqmDeleteStatement (org.hibernate.query.sqm.tree.delete.SqmDeleteStatement)2 SqmSetClause (org.hibernate.query.sqm.tree.update.SqmSetClause)2 SqmUpdateStatement (org.hibernate.query.sqm.tree.update.SqmUpdateStatement)2 DeleteStatement (org.hibernate.sql.ast.tree.delete.DeleteStatement)2