Search in sources :

Example 6 with JdbcSelect

use of org.hibernate.sql.exec.spi.JdbcSelect in project hibernate-orm by hibernate.

the class ConcreteSqmSelectQueryPlan method buildCacheableSqmInterpretation.

private static CacheableSqmInterpretation buildCacheableSqmInterpretation(SqmSelectStatement<?> sqm, DomainParameterXref domainParameterXref, DomainQueryExecutionContext executionContext) {
    final SharedSessionContractImplementor session = executionContext.getSession();
    final SessionFactoryImplementor sessionFactory = session.getFactory();
    final QueryEngine queryEngine = sessionFactory.getQueryEngine();
    final SqmTranslatorFactory sqmTranslatorFactory = queryEngine.getSqmTranslatorFactory();
    final SqmTranslator<SelectStatement> sqmConverter = sqmTranslatorFactory.createSelectTranslator(sqm, executionContext.getQueryOptions(), domainParameterXref, executionContext.getQueryParameterBindings(), executionContext.getSession().getLoadQueryInfluencers(), sessionFactory, true);
    // tableGroupAccess = sqmConverter.getFromClauseAccess();
    final SqmTranslation<SelectStatement> sqmInterpretation = sqmConverter.translate();
    final FromClauseAccess tableGroupAccess = sqmConverter.getFromClauseAccess();
    final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
    final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
    final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
    final SqlAstTranslator<JdbcSelect> selectTranslator = sqlAstTranslatorFactory.buildSelectTranslator(sessionFactory, sqmInterpretation.getSqlAst());
    final Map<QueryParameterImplementor<?>, Map<SqmParameter<?>, List<List<JdbcParameter>>>> jdbcParamsXref = SqmUtil.generateJdbcParamsXref(domainParameterXref, sqmInterpretation::getJdbcParamsBySqmParam);
    final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(executionContext.getQueryParameterBindings(), domainParameterXref, jdbcParamsXref, session.getFactory().getRuntimeMetamodels().getMappingMetamodel(), tableGroupAccess::findTableGroup, new SqmParameterMappingModelResolutionAccess() {

        @Override
        @SuppressWarnings("unchecked")
        public <T> MappingModelExpressible<T> getResolvedMappingModelType(SqmParameter<T> parameter) {
            return (MappingModelExpressible<T>) sqmInterpretation.getSqmParameterMappingModelTypeResolutions().get(parameter);
        }
    }, session);
    final JdbcSelect jdbcSelect = selectTranslator.translate(jdbcParameterBindings, executionContext.getQueryOptions());
    return new CacheableSqmInterpretation(sqmInterpretation.getSqlAst(), jdbcSelect, tableGroupAccess, jdbcParamsXref, sqmInterpretation.getSqmParameterMappingModelTypeResolutions(), jdbcParameterBindings);
}
Also used : MappingModelExpressible(org.hibernate.metamodel.mapping.MappingModelExpressible) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) QueryEngine(org.hibernate.query.spi.QueryEngine) JdbcEnvironment(org.hibernate.engine.jdbc.env.spi.JdbcEnvironment) SqmSelectStatement(org.hibernate.query.sqm.tree.select.SqmSelectStatement) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) ArrayList(java.util.ArrayList) List(java.util.List) SqmTranslatorFactory(org.hibernate.query.sqm.sql.SqmTranslatorFactory) JdbcSelect(org.hibernate.sql.exec.spi.JdbcSelect) SqmParameterMappingModelResolutionAccess(org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor) SqlAstTranslatorFactory(org.hibernate.sql.ast.SqlAstTranslatorFactory) FromClauseAccess(org.hibernate.sql.ast.spi.FromClauseAccess) QueryParameterImplementor(org.hibernate.query.spi.QueryParameterImplementor) Map(java.util.Map) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings)

Example 7 with JdbcSelect

use of org.hibernate.sql.exec.spi.JdbcSelect in project hibernate-orm by hibernate.

the class InsertExecutionDelegate method insertRootTable.

private void insertRootTable(String tableExpression, int rows, String[] keyColumns, ExecutionContext executionContext) {
    final TableReference updatingTableReference = updatingTableGroup.getTableReference(updatingTableGroup.getNavigablePath(), tableExpression, true, true);
    final IdentifierGenerator identifierGenerator = entityDescriptor.getEntityPersister().getIdentifierGenerator();
    final List<Assignment> assignments = assignmentsByTable.get(updatingTableReference);
    if ((assignments == null || assignments.isEmpty()) && !(identifierGenerator instanceof PostInsertIdentifierGenerator)) {
        throw new IllegalStateException("There must be at least a single root table assignment");
    }
    final NamedTableReference dmlTableReference = resolveUnionTableReference(updatingTableReference, tableExpression);
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Create the SQL AST and convert it into a JdbcOperation
    final QuerySpec querySpec = new QuerySpec(true);
    final NamedTableReference temporaryTableReference = new NamedTableReference(insertStatement.getTargetTable().getTableExpression(), updatingTableReference.getIdentificationVariable(), false, sessionFactory);
    final TableGroupImpl temporaryTableGroup = new TableGroupImpl(updatingTableGroup.getNavigablePath(), null, temporaryTableReference, entityDescriptor);
    querySpec.getFromClause().addRoot(temporaryTableGroup);
    final InsertStatement insertStatement = new InsertStatement(dmlTableReference);
    insertStatement.setSourceSelectStatement(querySpec);
    for (Assignment assignment : assignments) {
        insertStatement.addTargetColumnReferences(assignment.getAssignable().getColumnReferences());
        for (ColumnReference columnReference : assignment.getAssignable().getColumnReferences()) {
            querySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, new ColumnReference(updatingTableReference.getIdentificationVariable(), columnReference.getColumnExpression(), false, null, null, columnReference.getJdbcMapping(), sessionFactory)));
        }
    }
    final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
    final Map<Object, Object> entityTableToRootIdentity;
    if (identifierGenerator instanceof PostInsertIdentifierGenerator) {
        final BasicEntityIdentifierMapping identifierMapping = (BasicEntityIdentifierMapping) entityDescriptor.getIdentifierMapping();
        final QuerySpec idSelectQuerySpec = new QuerySpec(true);
        idSelectQuerySpec.getFromClause().addRoot(temporaryTableGroup);
        final ColumnReference columnReference = new ColumnReference((String) null, TemporaryTable.ENTITY_TABLE_IDENTITY_COLUMN, false, null, null, identifierMapping.getJdbcMapping(), sessionFactory);
        idSelectQuerySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, columnReference));
        idSelectQuerySpec.addSortSpecification(new SortSpecification(columnReference, SortOrder.ASCENDING));
        final SelectStatement selectStatement = new SelectStatement(idSelectQuerySpec, Collections.singletonList(new BasicFetch<>(0, null, null, identifierMapping, null, FetchTiming.IMMEDIATE, null)));
        final JdbcSelect jdbcSelect = jdbcServices.getJdbcEnvironment().getSqlAstTranslatorFactory().buildSelectTranslator(sessionFactory, selectStatement).translate(null, executionContext.getQueryOptions());
        final List<Object> list = jdbcServices.getJdbcSelectExecutor().list(jdbcSelect, JdbcParameterBindings.NO_BINDINGS, executionContext, null, ListResultsConsumer.UniqueSemantic.NONE);
        entityTableToRootIdentity = new LinkedHashMap<>(list.size());
        for (Object o : list) {
            entityTableToRootIdentity.put(o, null);
        }
        querySpec.applyPredicate(new ComparisonPredicate(columnReference, ComparisonOperator.EQUAL, new JdbcParameterImpl(identifierMapping.getJdbcMapping())));
    } else {
        entityTableToRootIdentity = null;
        if (identifierGenerator instanceof OptimizableGenerator) {
            final Optimizer optimizer = ((OptimizableGenerator) identifierGenerator).getOptimizer();
            // but only if the target paths don't already contain the id
            if (optimizer != null && optimizer.getIncrementSize() > 1 && insertStatement.getTargetColumnReferences().stream().noneMatch(c -> keyColumns[0].equals(c.getColumnExpression()))) {
                final BasicEntityIdentifierMapping identifierMapping = (BasicEntityIdentifierMapping) entityDescriptor.getIdentifierMapping();
                final JdbcParameter rowNumber = new JdbcParameterImpl(identifierMapping.getJdbcMapping());
                final JdbcParameter rootIdentity = new JdbcParameterImpl(identifierMapping.getJdbcMapping());
                final List<Assignment> temporaryTableAssignments = new ArrayList<>(1);
                final ColumnReference idColumnReference = new ColumnReference((String) null, identifierMapping, sessionFactory);
                temporaryTableAssignments.add(new Assignment(idColumnReference, rootIdentity));
                final TemporaryTableColumn rowNumberColumn = entityTable.getColumns().get(entityTable.getColumns().size() - 1);
                final UpdateStatement updateStatement = new UpdateStatement(temporaryTableReference, temporaryTableAssignments, new ComparisonPredicate(new ColumnReference((String) null, rowNumberColumn.getColumnName(), false, null, null, rowNumberColumn.getJdbcMapping(), sessionFactory), ComparisonOperator.EQUAL, rowNumber));
                final JdbcUpdate jdbcUpdate = jdbcServices.getJdbcEnvironment().getSqlAstTranslatorFactory().buildUpdateTranslator(sessionFactory, updateStatement).translate(null, executionContext.getQueryOptions());
                final JdbcParameterBindings updateBindings = new JdbcParameterBindingsImpl(2);
                for (int i = 0; i < rows; i++) {
                    updateBindings.addBinding(rowNumber, new JdbcParameterBindingImpl(rowNumberColumn.getJdbcMapping(), i + 1));
                    updateBindings.addBinding(rootIdentity, new JdbcParameterBindingImpl(identifierMapping.getJdbcMapping(), identifierGenerator.generate(executionContext.getSession(), null)));
                    jdbcServices.getJdbcMutationExecutor().execute(jdbcUpdate, updateBindings, sql -> executionContext.getSession().getJdbcCoordinator().getStatementPreparer().prepareStatement(sql), (integer, preparedStatement) -> {
                    }, executionContext);
                }
                insertStatement.addTargetColumnReferences(new ColumnReference((String) null, keyColumns[0], false, null, null, identifierMapping.getJdbcMapping(), sessionFactory));
                querySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, new ColumnReference(updatingTableReference.getIdentificationVariable(), idColumnReference.getColumnExpression(), false, null, null, idColumnReference.getJdbcMapping(), sessionFactory)));
            }
        }
    }
    final JdbcInsert jdbcInsert = jdbcServices.getJdbcEnvironment().getSqlAstTranslatorFactory().buildInsertTranslator(sessionFactory, insertStatement).translate(null, executionContext.getQueryOptions());
    if (identifierGenerator instanceof PostInsertIdentifierGenerator) {
        final PostInsertIdentifierGenerator generator = (PostInsertIdentifierGenerator) identifierGenerator;
        final boolean generatedKeysEnabled = sessionFactory.getSessionFactoryOptions().isGetGeneratedKeysEnabled();
        final InsertGeneratedIdentifierDelegate identifierDelegate = generator.getInsertGeneratedIdentifierDelegate((PostInsertIdentityPersister) entityDescriptor.getEntityPersister(), jdbcServices.getDialect(), generatedKeysEnabled);
        final String finalSql = identifierDelegate.prepareIdentifierGeneratingInsert(jdbcInsert.getSql());
        final BasicEntityIdentifierMapping identifierMapping = (BasicEntityIdentifierMapping) entityDescriptor.getIdentifierMapping();
        final ValueBinder jdbcValueBinder = identifierMapping.getJdbcMapping().getJdbcValueBinder();
        for (Map.Entry<Object, Object> entry : entityTableToRootIdentity.entrySet()) {
            final Object rootIdentity = identifierDelegate.performInsert(finalSql, executionContext.getSession(), new Binder() {

                @Override
                public void bindValues(PreparedStatement ps) throws SQLException {
                    jdbcValueBinder.bind(ps, entry.getKey(), 1, executionContext.getSession());
                }

                @Override
                public Object getEntity() {
                    return null;
                }
            });
            entry.setValue(rootIdentity);
        }
        final JdbcParameter entityIdentity = new JdbcParameterImpl(identifierMapping.getJdbcMapping());
        final JdbcParameter rootIdentity = new JdbcParameterImpl(identifierMapping.getJdbcMapping());
        final List<Assignment> temporaryTableAssignments = new ArrayList<>(1);
        temporaryTableAssignments.add(new Assignment(new ColumnReference((String) null, identifierMapping, sessionFactory), rootIdentity));
        final UpdateStatement updateStatement = new UpdateStatement(temporaryTableReference, temporaryTableAssignments, new ComparisonPredicate(new ColumnReference((String) null, TemporaryTable.ENTITY_TABLE_IDENTITY_COLUMN, false, null, null, identifierMapping.getJdbcMapping(), sessionFactory), ComparisonOperator.EQUAL, entityIdentity));
        final JdbcUpdate jdbcUpdate = jdbcServices.getJdbcEnvironment().getSqlAstTranslatorFactory().buildUpdateTranslator(sessionFactory, updateStatement).translate(null, executionContext.getQueryOptions());
        final JdbcParameterBindings updateBindings = new JdbcParameterBindingsImpl(2);
        for (Map.Entry<Object, Object> entry : entityTableToRootIdentity.entrySet()) {
            updateBindings.addBinding(entityIdentity, new JdbcParameterBindingImpl(identifierMapping.getJdbcMapping(), entry.getKey()));
            updateBindings.addBinding(rootIdentity, new JdbcParameterBindingImpl(identifierMapping.getJdbcMapping(), entry.getValue()));
            jdbcServices.getJdbcMutationExecutor().execute(jdbcUpdate, updateBindings, sql -> executionContext.getSession().getJdbcCoordinator().getStatementPreparer().prepareStatement(sql), (integer, preparedStatement) -> {
            }, executionContext);
        }
    } else {
        jdbcServices.getJdbcMutationExecutor().execute(jdbcInsert, JdbcParameterBindings.NO_BINDINGS, sql -> executionContext.getSession().getJdbcCoordinator().getStatementPreparer().prepareStatement(sql), (integer, preparedStatement) -> {
        }, executionContext);
    }
}
Also used : CollectionHelper(org.hibernate.internal.util.collections.CollectionHelper) ExecutionContext(org.hibernate.sql.exec.spi.ExecutionContext) ValueBinder(org.hibernate.type.descriptor.ValueBinder) EntityMappingType(org.hibernate.metamodel.mapping.EntityMappingType) ComparisonPredicate(org.hibernate.sql.ast.tree.predicate.ComparisonPredicate) SqmUtil(org.hibernate.query.sqm.internal.SqmUtil) PostInsertIdentifierGenerator(org.hibernate.id.PostInsertIdentifierGenerator) Map(java.util.Map) JdbcParameterImpl(org.hibernate.sql.exec.internal.JdbcParameterImpl) Binder(org.hibernate.id.insert.Binder) ComparisonOperator(org.hibernate.query.sqm.ComparisonOperator) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) IdentifierGenerator(org.hibernate.id.IdentifierGenerator) Assignable(org.hibernate.sql.ast.tree.update.Assignable) Assignment(org.hibernate.sql.ast.tree.update.Assignment) Optimizer(org.hibernate.id.enhanced.Optimizer) PreparedStatement(java.sql.PreparedStatement) UpdateStatement(org.hibernate.sql.ast.tree.update.UpdateStatement) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) List(java.util.List) JdbcUpdate(org.hibernate.sql.exec.spi.JdbcUpdate) SqmParameter(org.hibernate.query.sqm.tree.expression.SqmParameter) AbstractEntityPersister(org.hibernate.persister.entity.AbstractEntityPersister) InsertStatement(org.hibernate.sql.ast.tree.insert.InsertStatement) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) TemporaryTableColumn(org.hibernate.dialect.temptable.TemporaryTableColumn) MappingModelExpressible(org.hibernate.metamodel.mapping.MappingModelExpressible) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor) BasicEntityIdentifierMapping(org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping) JdbcParameterBindingsImpl(org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl) TableGroupImpl(org.hibernate.query.results.TableGroupImpl) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference) OptimizableGenerator(org.hibernate.id.OptimizableGenerator) Function(java.util.function.Function) SemanticException(org.hibernate.query.SemanticException) SortOrder(org.hibernate.query.sqm.SortOrder) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings) BasicFetch(org.hibernate.sql.results.graph.basic.BasicFetch) SortSpecification(org.hibernate.sql.ast.tree.select.SortSpecification) ArrayList(java.util.ArrayList) TableReference(org.hibernate.sql.ast.tree.from.TableReference) LinkedHashMap(java.util.LinkedHashMap) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) SQLException(java.sql.SQLException) MultiTableSqmMutationConverter(org.hibernate.query.sqm.mutation.internal.MultiTableSqmMutationConverter) JdbcInsert(org.hibernate.sql.exec.spi.JdbcInsert) SqmParameterMappingModelResolutionAccess(org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess) UnionTableReference(org.hibernate.sql.ast.tree.from.UnionTableReference) PostInsertIdentityPersister(org.hibernate.id.PostInsertIdentityPersister) FetchTiming(org.hibernate.engine.FetchTiming) InsertGeneratedIdentifierDelegate(org.hibernate.id.insert.InsertGeneratedIdentifierDelegate) TemporaryTable(org.hibernate.dialect.temptable.TemporaryTable) ListResultsConsumer(org.hibernate.sql.results.spi.ListResultsConsumer) ModelPartContainer(org.hibernate.metamodel.mapping.ModelPartContainer) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) DomainQueryExecutionContext(org.hibernate.query.spi.DomainQueryExecutionContext) JdbcParameter(org.hibernate.sql.ast.tree.expression.JdbcParameter) JdbcParameterBindingImpl(org.hibernate.sql.exec.internal.JdbcParameterBindingImpl) SqmInsertStatement(org.hibernate.query.sqm.tree.insert.SqmInsertStatement) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) DomainParameterXref(org.hibernate.query.sqm.internal.DomainParameterXref) Collections(java.util.Collections) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) JdbcSelect(org.hibernate.sql.exec.spi.JdbcSelect) SQLException(java.sql.SQLException) OptimizableGenerator(org.hibernate.id.OptimizableGenerator) Optimizer(org.hibernate.id.enhanced.Optimizer) ArrayList(java.util.ArrayList) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) TemporaryTableColumn(org.hibernate.dialect.temptable.TemporaryTableColumn) InsertStatement(org.hibernate.sql.ast.tree.insert.InsertStatement) SqmInsertStatement(org.hibernate.query.sqm.tree.insert.SqmInsertStatement) ComparisonPredicate(org.hibernate.sql.ast.tree.predicate.ComparisonPredicate) Assignment(org.hibernate.sql.ast.tree.update.Assignment) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) ValueBinder(org.hibernate.type.descriptor.ValueBinder) Binder(org.hibernate.id.insert.Binder) TableReference(org.hibernate.sql.ast.tree.from.TableReference) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) UnionTableReference(org.hibernate.sql.ast.tree.from.UnionTableReference) JdbcUpdate(org.hibernate.sql.exec.spi.JdbcUpdate) TableGroupImpl(org.hibernate.query.results.TableGroupImpl) JdbcParameterImpl(org.hibernate.sql.exec.internal.JdbcParameterImpl) BasicFetch(org.hibernate.sql.results.graph.basic.BasicFetch) JdbcSelect(org.hibernate.sql.exec.spi.JdbcSelect) UpdateStatement(org.hibernate.sql.ast.tree.update.UpdateStatement) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) JdbcParameterBindingsImpl(org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl) JdbcParameter(org.hibernate.sql.ast.tree.expression.JdbcParameter) JdbcParameterBindingImpl(org.hibernate.sql.exec.internal.JdbcParameterBindingImpl) PreparedStatement(java.sql.PreparedStatement) BasicEntityIdentifierMapping(org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping) InsertGeneratedIdentifierDelegate(org.hibernate.id.insert.InsertGeneratedIdentifierDelegate) PostInsertIdentifierGenerator(org.hibernate.id.PostInsertIdentifierGenerator) JdbcInsert(org.hibernate.sql.exec.spi.JdbcInsert) SortSpecification(org.hibernate.sql.ast.tree.select.SortSpecification) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) ValueBinder(org.hibernate.type.descriptor.ValueBinder) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) PostInsertIdentifierGenerator(org.hibernate.id.PostInsertIdentifierGenerator) IdentifierGenerator(org.hibernate.id.IdentifierGenerator) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings)

Example 8 with JdbcSelect

use of org.hibernate.sql.exec.spi.JdbcSelect in project hibernate-orm by hibernate.

the class MatchingIdSelectionHelper method selectMatchingIds.

/**
 * Centralized selection of ids matching the restriction of the DELETE
 * or UPDATE SQM query
 */
public static List<Object> selectMatchingIds(SqmDeleteOrUpdateStatement sqmMutationStatement, DomainParameterXref domainParameterXref, DomainQueryExecutionContext executionContext) {
    final SessionFactoryImplementor factory = executionContext.getSession().getFactory();
    final EntityMappingType entityDescriptor = factory.getRuntimeMetamodels().getEntityMappingType(sqmMutationStatement.getTarget().getModel().getHibernateEntityName());
    final MultiTableSqmMutationConverter sqmConverter = new MultiTableSqmMutationConverter(entityDescriptor, sqmMutationStatement, sqmMutationStatement.getTarget(), domainParameterXref, executionContext.getQueryOptions(), executionContext.getSession().getLoadQueryInfluencers(), executionContext.getQueryParameterBindings(), factory);
    final Map<SqmParameter, List<JdbcParameter>> parameterResolutions;
    if (domainParameterXref.getSqmParameterCount() == 0) {
        parameterResolutions = Collections.emptyMap();
    } else {
        parameterResolutions = new IdentityHashMap<>();
    }
    final Predicate restriction = sqmConverter.visitWhereClause(sqmMutationStatement.getWhereClause(), columnReference -> {
    }, (sqmParam, mappingType, jdbcParameters) -> parameterResolutions.put(sqmParam, jdbcParameters));
    final SelectStatement matchingIdSelection = generateMatchingIdSelectStatement(entityDescriptor, sqmMutationStatement, true, restriction, sqmConverter, executionContext, factory);
    sqmConverter.getProcessingStateStack().push(new SqlAstQueryPartProcessingStateImpl(matchingIdSelection.getQuerySpec(), sqmConverter.getCurrentProcessingState(), sqmConverter.getSqlAstCreationState(), sqmConverter.getCurrentClauseStack()::getCurrent, true));
    entityDescriptor.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) -> {
                        matchingIdSelection.getDomainResultDescriptors().add(new BasicResult<>(selection.getValuesArrayPosition(), null, jdbcMapping.getJavaTypeDescriptor()));
                    });
                }
            }
        }
    });
    sqmConverter.getProcessingStateStack().pop();
    final JdbcServices jdbcServices = factory.getJdbcServices();
    final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
    final SqlAstTranslator<JdbcSelect> sqlAstSelectTranslator = jdbcEnvironment.getSqlAstTranslatorFactory().buildSelectTranslator(factory, matchingIdSelection);
    final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(executionContext.getQueryParameterBindings(), domainParameterXref, SqmUtil.generateJdbcParamsXref(domainParameterXref, sqmConverter), factory.getRuntimeMetamodels().getMappingMetamodel(), navigablePath -> sqmConverter.getMutatingTableGroup(), new SqmParameterMappingModelResolutionAccess() {

        @Override
        @SuppressWarnings("unchecked")
        public <T> MappingModelExpressible<T> getResolvedMappingModelType(SqmParameter<T> parameter) {
            return (MappingModelExpressible<T>) sqmConverter.getSqmParameterMappingModelExpressibleResolutions().get(parameter);
        }
    }, executionContext.getSession());
    final LockOptions lockOptions = executionContext.getQueryOptions().getLockOptions();
    final LockMode lockMode = lockOptions.getLockMode();
    // Acquire a WRITE lock for the rows that are about to be modified
    lockOptions.setLockMode(LockMode.WRITE);
    // Visit the table joins and reset the lock mode if we encounter OUTER joins that are not supported
    if (!jdbcEnvironment.getDialect().supportsOuterJoinForUpdate()) {
        matchingIdSelection.getQuerySpec().getFromClause().visitTableJoins(tableJoin -> {
            if (tableJoin.getJoinType() != SqlAstJoinType.INNER) {
                lockOptions.setLockMode(lockMode);
            }
        });
    }
    final JdbcSelect idSelectJdbcOperation = sqlAstSelectTranslator.translate(jdbcParameterBindings, executionContext.getQueryOptions());
    lockOptions.setLockMode(lockMode);
    return jdbcServices.getJdbcSelectExecutor().list(idSelectJdbcOperation, jdbcParameterBindings, SqmJdbcExecutionContextAdapter.omittingLockingAndPaging(executionContext), row -> row[0], ListResultsConsumer.UniqueSemantic.FILTER);
}
Also used : LockOptions(org.hibernate.LockOptions) MappingModelExpressible(org.hibernate.metamodel.mapping.MappingModelExpressible) PluralAttributeMapping(org.hibernate.metamodel.mapping.PluralAttributeMapping) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) JdbcEnvironment(org.hibernate.engine.jdbc.env.spi.JdbcEnvironment) Predicate(org.hibernate.sql.ast.tree.predicate.Predicate) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) SqlAstQueryPartProcessingStateImpl(org.hibernate.query.sqm.sql.internal.SqlAstQueryPartProcessingStateImpl) ArrayList(java.util.ArrayList) List(java.util.List) EntityMappingType(org.hibernate.metamodel.mapping.EntityMappingType) JdbcSelect(org.hibernate.sql.exec.spi.JdbcSelect) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) SqmParameterMappingModelResolutionAccess(org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) LockMode(org.hibernate.LockMode) EntityIdentifierMapping(org.hibernate.metamodel.mapping.EntityIdentifierMapping) SqmParameter(org.hibernate.query.sqm.tree.expression.SqmParameter) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings)

Example 9 with JdbcSelect

use of org.hibernate.sql.exec.spi.JdbcSelect in project hibernate-orm by hibernate.

the class SmokeTests method testConvertedHqlInterpretation.

@Test
public void testConvertedHqlInterpretation(SessionFactoryScope scope) {
    scope.inTransaction(session -> {
        final JdbcTypeRegistry jdbcTypeRegistry = session.getFactory().getTypeConfiguration().getJdbcTypeRegistry();
        final QueryImplementor<Gender> query = session.createQuery("select e.gender from SimpleEntity e", Gender.class);
        final SqmQueryImplementor<Gender> hqlQuery = (SqmQueryImplementor<Gender>) query;
        final SqmSelectStatement<Gender> sqmStatement = (SqmSelectStatement<Gender>) hqlQuery.getSqmStatement();
        final StandardSqmTranslator<SelectStatement> sqmConverter = new StandardSqmTranslator<>(sqmStatement, hqlQuery.getQueryOptions(), ((QuerySqmImpl<?>) hqlQuery).getDomainParameterXref(), query.getParameterBindings(), session.getLoadQueryInfluencers(), scope.getSessionFactory(), true);
        final SqmTranslation<SelectStatement> sqmInterpretation = sqmConverter.translate();
        final SelectStatement sqlAst = sqmInterpretation.getSqlAst();
        final FromClause fromClause = sqlAst.getQuerySpec().getFromClause();
        assertThat(fromClause.getRoots().size(), is(1));
        final TableGroup rootTableGroup = fromClause.getRoots().get(0);
        assertThat(rootTableGroup.getPrimaryTableReference(), notNullValue());
        assertThat(rootTableGroup.getPrimaryTableReference().getTableId(), is("mapping_simple_entity"));
        assertThat(rootTableGroup.getTableReferenceJoins().size(), is(0));
        assertThat(rootTableGroup.getTableGroupJoins().isEmpty(), is(true));
        // `s` is the "alias stem" for `SimpleEntity` and as it is the first entity with that stem in
        // the query the base becomes `s1`.  The primary table reference is always suffixed as `_0`
        assertThat(rootTableGroup.getPrimaryTableReference().getIdentificationVariable(), is("s1_0"));
        final SelectClause selectClause = sqlAst.getQuerySpec().getSelectClause();
        assertThat(selectClause.getSqlSelections().size(), is(1));
        final SqlSelection sqlSelection = selectClause.getSqlSelections().get(0);
        assertThat(sqlSelection.getJdbcResultSetIndex(), is(1));
        assertThat(sqlSelection.getValuesArrayPosition(), is(0));
        assertThat(sqlSelection.getJdbcValueExtractor(), notNullValue());
        assertThat(sqlSelection, instanceOf(SqlSelectionImpl.class));
        final Expression selectedExpression = sqlSelection.getExpression();
        assertThat(selectedExpression, instanceOf(ColumnReference.class));
        final ColumnReference columnReference = (ColumnReference) selectedExpression;
        assertThat(columnReference.renderSqlFragment(scope.getSessionFactory()), is("s1_0.gender"));
        final JdbcMappingContainer selectedExpressible = selectedExpression.getExpressionType();
        assertThat(selectedExpressible, instanceOf(BasicTypeImpl.class));
        final BasicTypeImpl<?> basicType = (BasicTypeImpl<?>) selectedExpressible;
        assertThat(basicType.getJavaTypeDescriptor().getJavaTypeClass(), AssignableMatcher.assignableTo(Integer.class));
        assertThat(basicType.getJdbcType(), is(jdbcTypeRegistry.getDescriptor(Types.TINYINT)));
        assertThat(sqlAst.getDomainResultDescriptors().size(), is(1));
        final DomainResult<?> domainResult = sqlAst.getDomainResultDescriptors().get(0);
        assertThat(domainResult, instanceOf(BasicResult.class));
        final BasicResult<?> scalarDomainResult = (BasicResult<?>) domainResult;
        assertThat(scalarDomainResult.getAssembler(), instanceOf(BasicResultAssembler.class));
        final BasicResultAssembler<?> assembler = (BasicResultAssembler<?>) scalarDomainResult.getAssembler();
        assertThat(assembler.getValueConverter(), notNullValue());
        assertThat(assembler.getValueConverter(), instanceOf(OrdinalEnumValueConverter.class));
        final NavigablePath expectedSelectedPath = new NavigablePath(SimpleEntity.class.getName(), "e").append("gender");
        assertThat(domainResult.getNavigablePath(), equalTo(expectedSelectedPath));
        assertThat(domainResult, instanceOf(BasicResult.class));
        // ScalarDomainResultImpl creates and caches the assembler at its creation.
        // this just gets access to that cached one
        final DomainResultAssembler<?> resultAssembler = domainResult.createResultAssembler(null, null);
        assertThat(resultAssembler, instanceOf(BasicResultAssembler.class));
        final BasicValueConverter<?, ?> valueConverter = ((BasicResultAssembler<?>) resultAssembler).getValueConverter();
        assertThat(valueConverter, notNullValue());
        assertThat(valueConverter, instanceOf(OrdinalEnumValueConverter.class));
        final JdbcSelect jdbcSelectOperation = new StandardSqlAstTranslator<JdbcSelect>(session.getSessionFactory(), sqlAst).translate(null, QueryOptions.NONE);
        assertThat(jdbcSelectOperation.getSql(), is("select s1_0.gender from mapping_simple_entity s1_0"));
    });
}
Also used : SelectClause(org.hibernate.sql.ast.tree.select.SelectClause) NavigablePath(org.hibernate.query.spi.NavigablePath) BasicTypeImpl(org.hibernate.type.internal.BasicTypeImpl) Gender(org.hibernate.orm.test.mapping.SmokeTests.Gender) SqlSelection(org.hibernate.sql.ast.spi.SqlSelection) SqmSelectStatement(org.hibernate.query.sqm.tree.select.SqmSelectStatement) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) JdbcMappingContainer(org.hibernate.metamodel.mapping.JdbcMappingContainer) SqmQueryImplementor(org.hibernate.query.hql.spi.SqmQueryImplementor) BasicResult(org.hibernate.sql.results.graph.basic.BasicResult) OrdinalEnumValueConverter(org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter) SqmSelectStatement(org.hibernate.query.sqm.tree.select.SqmSelectStatement) JdbcSelect(org.hibernate.sql.exec.spi.JdbcSelect) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) BasicResultAssembler(org.hibernate.sql.results.graph.basic.BasicResultAssembler) FromClause(org.hibernate.sql.ast.tree.from.FromClause) Expression(org.hibernate.sql.ast.tree.expression.Expression) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) StandardSqmTranslator(org.hibernate.query.sqm.sql.internal.StandardSqmTranslator) JdbcTypeRegistry(org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference) Test(org.junit.jupiter.api.Test)

Example 10 with JdbcSelect

use of org.hibernate.sql.exec.spi.JdbcSelect in project hibernate-orm by hibernate.

the class SmokeTests method testSimpleHqlInterpretation.

@Test
public void testSimpleHqlInterpretation(SessionFactoryScope scope) {
    scope.inTransaction(session -> {
        final QueryImplementor<String> query = session.createQuery("select e.name from SimpleEntity e", String.class);
        final SqmQueryImplementor<String> hqlQuery = (SqmQueryImplementor<String>) query;
        final SqmSelectStatement<String> sqmStatement = (SqmSelectStatement<String>) hqlQuery.getSqmStatement();
        final StandardSqmTranslator<SelectStatement> sqmConverter = new StandardSqmTranslator<>(sqmStatement, hqlQuery.getQueryOptions(), ((QuerySqmImpl<?>) hqlQuery).getDomainParameterXref(), query.getParameterBindings(), session.getLoadQueryInfluencers(), scope.getSessionFactory(), true);
        final SqmTranslation<SelectStatement> sqmInterpretation = sqmConverter.translate();
        final SelectStatement sqlAst = sqmInterpretation.getSqlAst();
        final FromClause fromClause = sqlAst.getQuerySpec().getFromClause();
        assertThat(fromClause.getRoots().size(), is(1));
        final TableGroup rootTableGroup = fromClause.getRoots().get(0);
        assertThat(rootTableGroup.getPrimaryTableReference(), notNullValue());
        assertThat(rootTableGroup.getPrimaryTableReference().getTableId(), is("mapping_simple_entity"));
        assertThat(rootTableGroup.getTableReferenceJoins().size(), is(0));
        assertThat(rootTableGroup.getTableGroupJoins().isEmpty(), is(true));
        // `s` is the "alias stem" for `SimpleEntity` and as it is the first entity with that stem in
        // the query the base becomes `s1`.  The primary table reference is always suffixed as `_0`
        assertThat(rootTableGroup.getPrimaryTableReference().getIdentificationVariable(), is("s1_0"));
        final SelectClause selectClause = sqlAst.getQuerySpec().getSelectClause();
        assertThat(selectClause.getSqlSelections().size(), is(1));
        final SqlSelection sqlSelection = selectClause.getSqlSelections().get(0);
        assertThat(sqlSelection.getJdbcResultSetIndex(), is(1));
        assertThat(sqlSelection.getValuesArrayPosition(), is(0));
        assertThat(sqlSelection.getJdbcValueExtractor(), notNullValue());
        final JdbcSelect jdbcSelectOperation = new StandardSqlAstTranslator<JdbcSelect>(session.getSessionFactory(), sqlAst).translate(null, QueryOptions.NONE);
        assertThat(jdbcSelectOperation.getSql(), is("select s1_0.name from mapping_simple_entity s1_0"));
    });
}
Also used : SqmSelectStatement(org.hibernate.query.sqm.tree.select.SqmSelectStatement) SelectClause(org.hibernate.sql.ast.tree.select.SelectClause) JdbcSelect(org.hibernate.sql.exec.spi.JdbcSelect) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) SqlSelection(org.hibernate.sql.ast.spi.SqlSelection) SqmSelectStatement(org.hibernate.query.sqm.tree.select.SqmSelectStatement) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) SqmQueryImplementor(org.hibernate.query.hql.spi.SqmQueryImplementor) FromClause(org.hibernate.sql.ast.tree.from.FromClause) StandardSqmTranslator(org.hibernate.query.sqm.sql.internal.StandardSqmTranslator) Test(org.junit.jupiter.api.Test)

Aggregations

JdbcSelect (org.hibernate.sql.exec.spi.JdbcSelect)21 JdbcParameterBindings (org.hibernate.sql.exec.spi.JdbcParameterBindings)17 JdbcServices (org.hibernate.engine.jdbc.spi.JdbcServices)16 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)14 SelectStatement (org.hibernate.sql.ast.tree.select.SelectStatement)14 JdbcEnvironment (org.hibernate.engine.jdbc.env.spi.JdbcEnvironment)13 JdbcParameterBindingsImpl (org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl)13 SharedSessionContractImplementor (org.hibernate.engine.spi.SharedSessionContractImplementor)12 QueryParameterBindings (org.hibernate.query.spi.QueryParameterBindings)12 SqlAstTranslatorFactory (org.hibernate.sql.ast.SqlAstTranslatorFactory)12 ArrayList (java.util.ArrayList)11 ExecutionContext (org.hibernate.sql.exec.spi.ExecutionContext)11 QueryOptions (org.hibernate.query.spi.QueryOptions)10 Callback (org.hibernate.sql.exec.spi.Callback)10 JdbcParameter (org.hibernate.sql.ast.tree.expression.JdbcParameter)9 TableGroup (org.hibernate.sql.ast.tree.from.TableGroup)6 List (java.util.List)5 EntityKey (org.hibernate.engine.spi.EntityKey)5 SubselectFetch (org.hibernate.engine.spi.SubselectFetch)5 MappingModelExpressible (org.hibernate.metamodel.mapping.MappingModelExpressible)5