Search in sources :

Example 1 with InSubQueryPredicate

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;
}
Also used : CteColumn(org.hibernate.sql.ast.tree.cte.CteColumn) SelectClause(org.hibernate.sql.ast.tree.select.SelectClause) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) InSubQueryPredicate(org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate) CteTableGroup(org.hibernate.sql.ast.tree.cte.CteTableGroup) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) Expression(org.hibernate.sql.ast.tree.expression.Expression) SqlTuple(org.hibernate.sql.ast.tree.expression.SqlTuple) Junction(org.hibernate.sql.ast.tree.predicate.Junction) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference)

Example 2 with InSubQueryPredicate

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);
}
Also used : MutatingTableReferenceGroupWrapper(org.hibernate.sql.ast.tree.from.MutatingTableReferenceGroupWrapper) NavigablePath(org.hibernate.query.spi.NavigablePath) SqmParameterMappingModelResolutionAccess(org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess) MappingModelExpressible(org.hibernate.metamodel.mapping.MappingModelExpressible) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) InSubQueryPredicate(org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) Expression(org.hibernate.sql.ast.tree.expression.Expression) ForeignKeyDescriptor(org.hibernate.metamodel.mapping.ForeignKeyDescriptor) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) JdbcDelete(org.hibernate.sql.exec.spi.JdbcDelete) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings)

Example 3 with InSubQueryPredicate

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());
}
Also used : SqlAstQueryPartProcessingStateImpl(org.hibernate.query.sqm.sql.internal.SqlAstQueryPartProcessingStateImpl) EntityCollectionPart(org.hibernate.metamodel.mapping.internal.EntityCollectionPart) VirtualTableGroup(org.hibernate.sql.ast.tree.from.VirtualTableGroup) LazyTableGroup(org.hibernate.sql.ast.tree.from.LazyTableGroup) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) CorrelatedTableGroup(org.hibernate.sql.ast.tree.from.CorrelatedTableGroup) CorrelatedPluralTableGroup(org.hibernate.sql.ast.tree.from.CorrelatedPluralTableGroup) PluralTableGroup(org.hibernate.sql.ast.tree.from.PluralTableGroup) QueryPartTableGroup(org.hibernate.sql.ast.tree.from.QueryPartTableGroup) EmbeddedCollectionPart(org.hibernate.metamodel.mapping.internal.EmbeddedCollectionPart) FromClauseAccess(org.hibernate.sql.ast.spi.FromClauseAccess) BinaryArithmeticExpression(org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression) SqmModifiedSubQueryExpression(org.hibernate.query.sqm.tree.expression.SqmModifiedSubQueryExpression) SelfRenderingFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression) SelfRenderingAggregateFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingAggregateFunctionSqlAstExpression) CaseSearchedExpression(org.hibernate.sql.ast.tree.expression.CaseSearchedExpression) SelfRenderingSqlFragmentExpression(org.hibernate.sql.ast.tree.expression.SelfRenderingSqlFragmentExpression) Expression(org.hibernate.sql.ast.tree.expression.Expression) SelfRenderingExpression(org.hibernate.sql.ast.tree.expression.SelfRenderingExpression) SqmExpression(org.hibernate.query.sqm.tree.expression.SqmExpression) CaseSimpleExpression(org.hibernate.sql.ast.tree.expression.CaseSimpleExpression) SqlSelectionExpression(org.hibernate.sql.ast.tree.expression.SqlSelectionExpression) ModifiedSubQueryExpression(org.hibernate.sql.ast.tree.expression.ModifiedSubQueryExpression) InSubQueryPredicate(org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate) SqmInSubQueryPredicate(org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate) PluralAttributeMapping(org.hibernate.metamodel.mapping.PluralAttributeMapping) SqmQuerySpec(org.hibernate.query.sqm.tree.select.SqmQuerySpec) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) EntityCollectionPart(org.hibernate.metamodel.mapping.internal.EntityCollectionPart) CollectionPart(org.hibernate.metamodel.mapping.CollectionPart) EmbeddedCollectionPart(org.hibernate.metamodel.mapping.internal.EmbeddedCollectionPart)

Example 4 with InSubQueryPredicate

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);
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) SqmParameterMappingModelResolutionAccess(org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess) MappingModelExpressible(org.hibernate.metamodel.mapping.MappingModelExpressible) InSubQueryPredicate(org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate) MutableInteger(org.hibernate.internal.util.MutableInteger) UnionTableReference(org.hibernate.sql.ast.tree.from.UnionTableReference) ForeignKeyDescriptor(org.hibernate.metamodel.mapping.ForeignKeyDescriptor) Joinable(org.hibernate.persister.entity.Joinable) EntityIdentifierMapping(org.hibernate.metamodel.mapping.EntityIdentifierMapping) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings)

Example 5 with InSubQueryPredicate

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;
}
Also used : ForeignKeyDescriptor(org.hibernate.metamodel.mapping.ForeignKeyDescriptor) InSubQueryPredicate(org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate) EntityIdentifierMapping(org.hibernate.metamodel.mapping.EntityIdentifierMapping) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec)

Aggregations

InSubQueryPredicate (org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate)10 Expression (org.hibernate.sql.ast.tree.expression.Expression)6 ColumnReference (org.hibernate.sql.ast.tree.expression.ColumnReference)5 NamedTableReference (org.hibernate.sql.ast.tree.from.NamedTableReference)5 QuerySpec (org.hibernate.sql.ast.tree.select.QuerySpec)5 ForeignKeyDescriptor (org.hibernate.metamodel.mapping.ForeignKeyDescriptor)4 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)3 EntityIdentifierMapping (org.hibernate.metamodel.mapping.EntityIdentifierMapping)3 SqlTuple (org.hibernate.sql.ast.tree.expression.SqlTuple)3 ArrayList (java.util.ArrayList)2 JdbcServices (org.hibernate.engine.jdbc.spi.JdbcServices)2 CollectionPart (org.hibernate.metamodel.mapping.CollectionPart)2 MappingModelExpressible (org.hibernate.metamodel.mapping.MappingModelExpressible)2 SqmParameterMappingModelResolutionAccess (org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess)2 SqmDeleteStatement (org.hibernate.query.sqm.tree.delete.SqmDeleteStatement)2 SqmExpression (org.hibernate.query.sqm.tree.expression.SqmExpression)2 DeleteStatement (org.hibernate.sql.ast.tree.delete.DeleteStatement)2 TableReference (org.hibernate.sql.ast.tree.from.TableReference)2 QueryPart (org.hibernate.sql.ast.tree.select.QueryPart)2 JdbcParameterBindings (org.hibernate.sql.exec.spi.JdbcParameterBindings)2