Search in sources :

Example 1 with MutationStatement

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

the class AbstractSqlAstTranslator method visitUpdateStatement.

@Override
public void visitUpdateStatement(UpdateStatement statement) {
    MutationStatement oldDmlTargetTableAlias = dmlStatement;
    dmlStatement = null;
    try {
        visitCteContainer(statement);
        dmlStatement = statement;
        visitUpdateStatementOnly(statement);
    } finally {
        dmlStatement = oldDmlTargetTableAlias;
    }
}
Also used : MutationStatement(org.hibernate.sql.ast.tree.MutationStatement)

Example 2 with MutationStatement

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

the class AbstractSqlAstTranslator method visitSelectStatement.

@Override
public void visitSelectStatement(SelectStatement statement) {
    MutationStatement oldDmlStatement = dmlStatement;
    dmlStatement = null;
    try {
        visitCteContainer(statement);
        statement.getQueryPart().accept(this);
    } finally {
        dmlStatement = oldDmlStatement;
    }
}
Also used : MutationStatement(org.hibernate.sql.ast.tree.MutationStatement)

Example 3 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 CteTable dmlResultCte = new CteTable(getCteTableName(tableExpression), 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 4 with MutationStatement

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

the class CteUpdateHandler 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 SqmUpdateStatement<?> updateStatement = (SqmUpdateStatement<?>) getSqmDeleteOrUpdateStatement();
    final EntityMappingType entityDescriptor = getEntityDescriptor();
    final EntityPersister entityPersister = entityDescriptor.getEntityPersister();
    final String rootEntityName = entityPersister.getRootEntityName();
    final EntityPersister rootEntityDescriptor = factory.getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor(rootEntityName);
    final String hierarchyRootTableName = ((Joinable) rootEntityDescriptor).getTableName();
    final TableReference hierarchyRootTableReference = updatingTableGroup.resolveTableReference(updatingTableGroup.getNavigablePath(), hierarchyRootTableName);
    assert hierarchyRootTableReference != null;
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // visit the set-clause using our special converter, collecting
    // information about the assignments
    final SqmSetClause setClause = updateStatement.getSetClause();
    final List<Assignment> assignments = new ArrayList<>(setClause.getAssignments().size());
    final Map<SqmParameter, MappingModelExpressible> paramTypeResolutions = new LinkedHashMap<>();
    sqmConverter.visitSetClause(setClause, assignments::add, (sqmParam, mappingType, jdbcParameters) -> {
        parameterResolutions.put(sqmParam, jdbcParameters);
        paramTypeResolutions.put(sqmParam, mappingType);
    });
    sqmConverter.addVersionedAssignment(assignments::add, updateStatement);
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // cross-reference the TableReference by alias.  The TableGroup already
    // cross-references it by name, but 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);
    }
    final Map<TableReference, List<Assignment>> assignmentsByTable = CollectionHelper.mapOfSize(updatingTableGroup.getTableReferenceJoins().size() + 1);
    for (int i = 0; i < assignments.size(); i++) {
        final Assignment assignment = assignments.get(i);
        final List<ColumnReference> assignmentColumnRefs = assignment.getAssignable().getColumnReferences();
        TableReference assignmentTableReference = null;
        for (int c = 0; c < assignmentColumnRefs.size(); c++) {
            final ColumnReference columnReference = assignmentColumnRefs.get(c);
            final TableReference tableReference = resolveTableReference(columnReference, tableReferenceByAlias);
            // TODO: this could be fixed by introducing joins to DML statements
            if (assignmentTableReference != null && !assignmentTableReference.equals(tableReference)) {
                throw new IllegalStateException("Assignment referred to columns from multiple tables");
            }
            assignmentTableReference = tableReference;
        }
        assert assignmentTableReference != null;
        List<Assignment> assignmentsForTable = assignmentsByTable.get(assignmentTableReference);
        if (assignmentsForTable == null) {
            assignmentsForTable = new ArrayList<>();
            assignmentsByTable.put(assignmentTableReference, assignmentsForTable);
        }
        assignmentsForTable.add(assignment);
    }
    getEntityDescriptor().visitConstraintOrderedTables((tableExpression, tableColumnsVisitationSupplier) -> {
        final CteTable dmlResultCte = new CteTable(getCteTableName(tableExpression), idSelectCte.getCteTable().getCteColumns(), factory);
        final TableReference updatingTableReference = updatingTableGroup.getTableReference(updatingTableGroup.getNavigablePath(), tableExpression, true, true);
        final List<Assignment> assignmentList = assignmentsByTable.get(updatingTableReference);
        if (assignmentList == null) {
            return;
        }
        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 UpdateStatement(dmlTableReference, assignmentList, createIdSubQueryPredicate(columnReferences, idSelectCte, factory), columnReferences);
        statement.addCteStatement(new CteStatement(dmlResultCte, dmlStatement));
    });
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) MappingModelExpressible(org.hibernate.metamodel.mapping.MappingModelExpressible) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Assignment(org.hibernate.sql.ast.tree.update.Assignment) TableReference(org.hibernate.sql.ast.tree.from.TableReference) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) SqmCteTable(org.hibernate.query.sqm.tree.cte.SqmCteTable) CteTable(org.hibernate.sql.ast.tree.cte.CteTable) CteStatement(org.hibernate.sql.ast.tree.cte.CteStatement) ArrayList(java.util.ArrayList) List(java.util.List) SqmSetClause(org.hibernate.query.sqm.tree.update.SqmSetClause) EntityMappingType(org.hibernate.metamodel.mapping.EntityMappingType) SqmUpdateStatement(org.hibernate.query.sqm.tree.update.SqmUpdateStatement) UpdateStatement(org.hibernate.sql.ast.tree.update.UpdateStatement) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) SqmUpdateStatement(org.hibernate.query.sqm.tree.update.SqmUpdateStatement) MutationStatement(org.hibernate.sql.ast.tree.MutationStatement) Joinable(org.hibernate.persister.entity.Joinable) SqmParameter(org.hibernate.query.sqm.tree.expression.SqmParameter) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference)

Example 5 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)6 ArrayList (java.util.ArrayList)2 SqmCteTable (org.hibernate.query.sqm.tree.cte.SqmCteTable)2 CteStatement (org.hibernate.sql.ast.tree.cte.CteStatement)2 CteTable (org.hibernate.sql.ast.tree.cte.CteTable)2 ColumnReference (org.hibernate.sql.ast.tree.expression.ColumnReference)2 NamedTableReference (org.hibernate.sql.ast.tree.from.NamedTableReference)2 TableGroup (org.hibernate.sql.ast.tree.from.TableGroup)2 TableReference (org.hibernate.sql.ast.tree.from.TableReference)2 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 EntityIdentifierMapping (org.hibernate.metamodel.mapping.EntityIdentifierMapping)1 EntityMappingType (org.hibernate.metamodel.mapping.EntityMappingType)1 MappingModelExpressible (org.hibernate.metamodel.mapping.MappingModelExpressible)1 PluralAttributeMapping (org.hibernate.metamodel.mapping.PluralAttributeMapping)1 EntityPersister (org.hibernate.persister.entity.EntityPersister)1 Joinable (org.hibernate.persister.entity.Joinable)1 SqlAstQueryPartProcessingStateImpl (org.hibernate.query.sqm.sql.internal.SqlAstQueryPartProcessingStateImpl)1 SqmDeleteStatement (org.hibernate.query.sqm.tree.delete.SqmDeleteStatement)1 SqmParameter (org.hibernate.query.sqm.tree.expression.SqmParameter)1