Search in sources :

Example 16 with SqlSelectionImpl

use of org.hibernate.sql.results.internal.SqlSelectionImpl in project hibernate-orm by hibernate.

the class ExecuteWithoutIdTableHelper method createIdMatchingSubQuerySpec.

public static QuerySpec createIdMatchingSubQuerySpec(NavigablePath navigablePath, TableReference rootTableReference, Predicate predicate, EntityPersister rootEntityPersister, SqlExpressionResolver sqlExpressionResolver, SessionFactoryImplementor sessionFactory) {
    /*
		 * `select root_id from root_table where {predicate}
		 */
    final QuerySpec matchingIdSelect = new QuerySpec(false, 1);
    final StandardTableGroup matchingIdSelectTableGroup = new StandardTableGroup(true, navigablePath, rootEntityPersister, rootTableReference.getIdentificationVariable(), rootTableReference, null, sessionFactory);
    matchingIdSelect.getFromClause().addRoot(matchingIdSelectTableGroup);
    rootEntityPersister.getIdentifierMapping().forEachSelectable((columnIndex, selection) -> {
        final ColumnReference columnReference = (ColumnReference) sqlExpressionResolver.resolveSqlExpression(SqlExpressionResolver.createColumnReferenceKey(rootTableReference, selection.getSelectionExpression()), sqlAstProcessingState -> new ColumnReference(rootTableReference, selection, sessionFactory));
        final SqlSelection sqlSelection = new SqlSelectionImpl(// irrelevant
        0, 0, columnReference);
        matchingIdSelect.getSelectClause().addSqlSelection(sqlSelection);
    });
    matchingIdSelect.applyPredicate(predicate);
    return matchingIdSelect;
}
Also used : StandardTableGroup(org.hibernate.sql.ast.tree.from.StandardTableGroup) Predicate(org.hibernate.sql.ast.tree.predicate.Predicate) EntityPersister(org.hibernate.persister.entity.EntityPersister) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) NavigablePath(org.hibernate.query.spi.NavigablePath) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) StandardTableGroup(org.hibernate.sql.ast.tree.from.StandardTableGroup) SqlSelection(org.hibernate.sql.ast.spi.SqlSelection) SqlExpressionResolver(org.hibernate.sql.ast.spi.SqlExpressionResolver) TableReference(org.hibernate.sql.ast.tree.from.TableReference) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference) SqlSelection(org.hibernate.sql.ast.spi.SqlSelection)

Example 17 with SqlSelectionImpl

use of org.hibernate.sql.results.internal.SqlSelectionImpl in project hibernate-orm by hibernate.

the class InsertExecutionDelegate method insertTable.

private void insertTable(String tableExpression, String[] keyColumns, boolean nullableTable, ExecutionContext executionContext) {
    final TableReference updatingTableReference = updatingTableGroup.getTableReference(updatingTableGroup.getNavigablePath(), tableExpression, true, true);
    final List<Assignment> assignments = assignmentsByTable.get(updatingTableReference);
    if (nullableTable && (assignments == null || assignments.isEmpty())) {
        // no assignments for this table - skip it
        return;
    }
    final NamedTableReference dmlTargetTableReference = resolveUnionTableReference(updatingTableReference, tableExpression);
    final QuerySpec querySpec = new QuerySpec(true);
    final TableGroupImpl temporaryTableGroup = new TableGroupImpl(updatingTableGroup.getNavigablePath(), null, new NamedTableReference(insertStatement.getTargetTable().getTableExpression(), updatingTableReference.getIdentificationVariable(), false, sessionFactory), entityDescriptor);
    querySpec.getFromClause().addRoot(temporaryTableGroup);
    final InsertStatement insertStatement = new InsertStatement(dmlTargetTableReference);
    insertStatement.setSourceSelectStatement(querySpec);
    if (assignments != null && !assignments.isEmpty()) {
        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 String targetKeyColumnName = keyColumns[0];
    final AbstractEntityPersister entityPersister = (AbstractEntityPersister) entityDescriptor.getEntityPersister();
    final IdentifierGenerator identifierGenerator = entityPersister.getIdentifierGenerator();
    final boolean needsKeyInsert;
    if (identifierGenerator instanceof PostInsertIdentifierGenerator) {
        needsKeyInsert = true;
    } else if (identifierGenerator instanceof OptimizableGenerator) {
        final Optimizer optimizer = ((OptimizableGenerator) identifierGenerator).getOptimizer();
        // If the generator uses an optimizer, we have to generate the identifiers for the new rows
        needsKeyInsert = optimizer != null && optimizer.getIncrementSize() > 1;
    } else {
        needsKeyInsert = false;
    }
    if (needsKeyInsert && insertStatement.getTargetColumnReferences().stream().noneMatch(c -> targetKeyColumnName.equals(c.getColumnExpression()))) {
        final BasicEntityIdentifierMapping identifierMapping = (BasicEntityIdentifierMapping) entityDescriptor.getIdentifierMapping();
        insertStatement.addTargetColumnReferences(new ColumnReference(dmlTargetTableReference.getIdentificationVariable(), targetKeyColumnName, false, null, null, identifierMapping.getJdbcMapping(), sessionFactory));
        querySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, new ColumnReference(updatingTableReference.getIdentificationVariable(), identifierMapping, sessionFactory)));
    }
    final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
    final JdbcInsert jdbcInsert = jdbcServices.getJdbcEnvironment().getSqlAstTranslatorFactory().buildInsertTranslator(sessionFactory, insertStatement).translate(null, executionContext.getQueryOptions());
    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) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) OptimizableGenerator(org.hibernate.id.OptimizableGenerator) Optimizer(org.hibernate.id.enhanced.Optimizer) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) BasicEntityIdentifierMapping(org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping) InsertStatement(org.hibernate.sql.ast.tree.insert.InsertStatement) SqmInsertStatement(org.hibernate.query.sqm.tree.insert.SqmInsertStatement) Assignment(org.hibernate.sql.ast.tree.update.Assignment) PostInsertIdentifierGenerator(org.hibernate.id.PostInsertIdentifierGenerator) TableReference(org.hibernate.sql.ast.tree.from.TableReference) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) UnionTableReference(org.hibernate.sql.ast.tree.from.UnionTableReference) JdbcInsert(org.hibernate.sql.exec.spi.JdbcInsert) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) TableGroupImpl(org.hibernate.query.results.TableGroupImpl) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) AbstractEntityPersister(org.hibernate.persister.entity.AbstractEntityPersister) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference) PostInsertIdentifierGenerator(org.hibernate.id.PostInsertIdentifierGenerator) IdentifierGenerator(org.hibernate.id.IdentifierGenerator)

Example 18 with SqlSelectionImpl

use of org.hibernate.sql.results.internal.SqlSelectionImpl in project hibernate-orm by hibernate.

the class TableBasedInsertHandler method resolveDelegate.

private ExecutionDelegate resolveDelegate(DomainQueryExecutionContext executionContext) {
    final EntityPersister entityDescriptor = sessionFactory.getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor(getSqmInsertStatement().getTarget().getEntityName());
    final MultiTableSqmMutationConverter converterDelegate = new MultiTableSqmMutationConverter(entityDescriptor, getSqmInsertStatement(), getSqmInsertStatement().getTarget(), domainParameterXref, executionContext.getQueryOptions(), executionContext.getSession().getLoadQueryInfluencers(), executionContext.getQueryParameterBindings(), sessionFactory);
    final TableGroup insertingTableGroup = converterDelegate.getMutatingTableGroup();
    final Map<SqmParameter<?>, List<List<JdbcParameter>>> parameterResolutions;
    if (domainParameterXref.getSqmParameterCount() == 0) {
        parameterResolutions = Collections.emptyMap();
    } else {
        parameterResolutions = new IdentityHashMap<>();
    }
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // visit the insertion target using our special converter, collecting
    // information about the target paths
    final List<Assignment> targetPathColumns = new ArrayList<>();
    final Map<SqmParameter<?>, MappingModelExpressible<?>> paramTypeResolutions = new LinkedHashMap<>();
    final NamedTableReference entityTableReference = new NamedTableReference(entityTable.getTableExpression(), TemporaryTable.DEFAULT_ALIAS, true, sessionFactory);
    final InsertStatement insertStatement = new InsertStatement(entityTableReference);
    final BaseSqmToSqlAstConverter.AdditionalInsertValues additionalInsertValues = converterDelegate.visitInsertionTargetPaths((assigable, columnReferences) -> {
        insertStatement.addTargetColumnReferences(columnReferences);
        targetPathColumns.add(new Assignment(assigable, (Expression) assigable));
    }, sqmInsertStatement, entityDescriptor, insertingTableGroup, (sqmParameter, mappingType, jdbcParameters) -> {
        parameterResolutions.computeIfAbsent(sqmParameter, k -> new ArrayList<>(1)).add(jdbcParameters);
        paramTypeResolutions.put(sqmParameter, mappingType);
    });
    if (sqmInsertStatement instanceof SqmInsertSelectStatement) {
        final QueryPart queryPart = converterDelegate.visitQueryPart(((SqmInsertSelectStatement<?>) sqmInsertStatement).getSelectQueryPart());
        queryPart.visitQuerySpecs(querySpec -> {
            if (additionalInsertValues.applySelections(querySpec, sessionFactory)) {
                final TemporaryTableColumn rowNumberColumn = entityTable.getColumns().get(entityTable.getColumns().size() - 1);
                final ColumnReference columnReference = new ColumnReference((String) null, rowNumberColumn.getColumnName(), false, null, null, rowNumberColumn.getJdbcMapping(), sessionFactory);
                insertStatement.getTargetColumnReferences().set(insertStatement.getTargetColumnReferences().size() - 1, columnReference);
                targetPathColumns.set(targetPathColumns.size() - 1, new Assignment(columnReference, columnReference));
            } else if (entityDescriptor.getIdentifierGenerator() instanceof OptimizableGenerator) {
                final Optimizer optimizer = ((OptimizableGenerator) entityDescriptor.getIdentifierGenerator()).getOptimizer();
                if (optimizer != null && optimizer.getIncrementSize() > 1) {
                    if (!sessionFactory.getJdbcServices().getDialect().supportsWindowFunctions()) {
                        return;
                    }
                    final TemporaryTableColumn rowNumberColumn = entityTable.getColumns().get(entityTable.getColumns().size() - 1);
                    final ColumnReference columnReference = new ColumnReference((String) null, rowNumberColumn.getColumnName(), false, null, null, rowNumberColumn.getJdbcMapping(), sessionFactory);
                    insertStatement.getTargetColumnReferences().add(columnReference);
                    targetPathColumns.add(new Assignment(columnReference, columnReference));
                    final BasicType<Integer> rowNumberType = sessionFactory.getTypeConfiguration().getBasicTypeForJavaType(Integer.class);
                    querySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, new Over<>(new SelfRenderingFunctionSqlAstExpression("row_number", (appender, args, walker) -> appender.appendSql("row_number()"), Collections.emptyList(), rowNumberType, rowNumberType), Collections.emptyList(), Collections.emptyList())));
                }
            }
        });
        insertStatement.setSourceSelectStatement(queryPart);
    } else {
        // Add the row number column if there is one
        final IdentifierGenerator generator = entityDescriptor.getIdentifierGenerator();
        final BasicType<?> rowNumberType;
        if (generator instanceof OptimizableGenerator) {
            final Optimizer optimizer = ((OptimizableGenerator) generator).getOptimizer();
            if (optimizer != null && optimizer.getIncrementSize() > 1) {
                final TemporaryTableColumn rowNumberColumn = entityTable.getColumns().get(entityTable.getColumns().size() - 1);
                rowNumberType = (BasicType<?>) rowNumberColumn.getJdbcMapping();
                final ColumnReference columnReference = new ColumnReference((String) null, rowNumberColumn.getColumnName(), false, null, null, rowNumberColumn.getJdbcMapping(), sessionFactory);
                insertStatement.getTargetColumnReferences().add(columnReference);
                targetPathColumns.add(new Assignment(columnReference, columnReference));
            } else {
                rowNumberType = null;
            }
        } else {
            rowNumberType = null;
        }
        final List<SqmValues> sqmValuesList = ((SqmInsertValuesStatement<?>) sqmInsertStatement).getValuesList();
        final List<Values> valuesList = new ArrayList<>(sqmValuesList.size());
        for (int i = 0; i < sqmValuesList.size(); i++) {
            final Values values = converterDelegate.visitValues(sqmValuesList.get(i));
            additionalInsertValues.applyValues(values);
            if (rowNumberType != null) {
                values.getExpressions().add(new QueryLiteral<>(i + 1, rowNumberType));
            }
            valuesList.add(values);
        }
        insertStatement.setValuesList(valuesList);
    }
    converterDelegate.pruneTableGroupJoins();
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // 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(insertingTableGroup.getTableReferenceJoins().size() + 1);
    collectTableReference(insertingTableGroup.getPrimaryTableReference(), tableReferenceByAlias::put);
    for (int i = 0; i < insertingTableGroup.getTableReferenceJoins().size(); i++) {
        collectTableReference(insertingTableGroup.getTableReferenceJoins().get(i), tableReferenceByAlias::put);
    }
    return new InsertExecutionDelegate(sqmInsertStatement, converterDelegate, entityTable, afterUseAction, sessionUidAccess, domainParameterXref, insertingTableGroup, tableReferenceByAlias, targetPathColumns, insertStatement, parameterResolutions, paramTypeResolutions, executionContext);
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) CollectionHelper(org.hibernate.internal.util.collections.CollectionHelper) ExecutionContext(org.hibernate.sql.exec.spi.ExecutionContext) EntityPersister(org.hibernate.persister.entity.EntityPersister) BasicType(org.hibernate.type.BasicType) Logger(org.jboss.logging.Logger) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference) SqmInsertValuesStatement(org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement) OptimizableGenerator(org.hibernate.id.OptimizableGenerator) Function(java.util.function.Function) ArrayList(java.util.ArrayList) SqmJdbcExecutionContextAdapter(org.hibernate.query.sqm.internal.SqmJdbcExecutionContextAdapter) TableReference(org.hibernate.sql.ast.tree.from.TableReference) LinkedHashMap(java.util.LinkedHashMap) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) MultiTableSqmMutationConverter(org.hibernate.query.sqm.mutation.internal.MultiTableSqmMutationConverter) Map(java.util.Map) BiConsumer(java.util.function.BiConsumer) TableReferenceJoin(org.hibernate.sql.ast.tree.from.TableReferenceJoin) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) SqmInsertSelectStatement(org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement) IdentifierGenerator(org.hibernate.id.IdentifierGenerator) Values(org.hibernate.sql.ast.tree.insert.Values) Assignment(org.hibernate.sql.ast.tree.update.Assignment) IdentityHashMap(java.util.IdentityHashMap) TemporaryTable(org.hibernate.dialect.temptable.TemporaryTable) SelfRenderingFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression) Optimizer(org.hibernate.id.enhanced.Optimizer) Expression(org.hibernate.sql.ast.tree.expression.Expression) QueryLiteral(org.hibernate.sql.ast.tree.expression.QueryLiteral) BaseSqmToSqlAstConverter(org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter) DomainQueryExecutionContext(org.hibernate.query.spi.DomainQueryExecutionContext) InsertHandler(org.hibernate.query.sqm.mutation.internal.InsertHandler) List(java.util.List) JdbcParameter(org.hibernate.sql.ast.tree.expression.JdbcParameter) SqmInsertStatement(org.hibernate.query.sqm.tree.insert.SqmInsertStatement) QueryPart(org.hibernate.sql.ast.tree.select.QueryPart) Over(org.hibernate.sql.ast.tree.expression.Over) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) SqmParameter(org.hibernate.query.sqm.tree.expression.SqmParameter) InsertStatement(org.hibernate.sql.ast.tree.insert.InsertStatement) DomainParameterXref(org.hibernate.query.sqm.internal.DomainParameterXref) Collections(java.util.Collections) TemporaryTableColumn(org.hibernate.dialect.temptable.TemporaryTableColumn) MappingModelExpressible(org.hibernate.metamodel.mapping.MappingModelExpressible) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) SqmValues(org.hibernate.query.sqm.tree.insert.SqmValues) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor) BasicType(org.hibernate.type.BasicType) MappingModelExpressible(org.hibernate.metamodel.mapping.MappingModelExpressible) QueryPart(org.hibernate.sql.ast.tree.select.QueryPart) OptimizableGenerator(org.hibernate.id.OptimizableGenerator) Optimizer(org.hibernate.id.enhanced.Optimizer) ArrayList(java.util.ArrayList) Values(org.hibernate.sql.ast.tree.insert.Values) SqmValues(org.hibernate.query.sqm.tree.insert.SqmValues) TemporaryTableColumn(org.hibernate.dialect.temptable.TemporaryTableColumn) SqmInsertStatement(org.hibernate.query.sqm.tree.insert.SqmInsertStatement) InsertStatement(org.hibernate.sql.ast.tree.insert.InsertStatement) 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) SqmValues(org.hibernate.query.sqm.tree.insert.SqmValues) ArrayList(java.util.ArrayList) List(java.util.List) SqmInsertSelectStatement(org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement) BaseSqmToSqlAstConverter(org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) JdbcParameter(org.hibernate.sql.ast.tree.expression.JdbcParameter) SqmInsertValuesStatement(org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement) SelfRenderingFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression) Expression(org.hibernate.sql.ast.tree.expression.Expression) SelfRenderingFunctionSqlAstExpression(org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) SqmParameter(org.hibernate.query.sqm.tree.expression.SqmParameter) MultiTableSqmMutationConverter(org.hibernate.query.sqm.mutation.internal.MultiTableSqmMutationConverter) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference) IdentifierGenerator(org.hibernate.id.IdentifierGenerator)

Example 19 with SqlSelectionImpl

use of org.hibernate.sql.results.internal.SqlSelectionImpl in project hibernate-orm by hibernate.

the class AbstractSqlAstTranslator method determineLateralEmulationPredicate.

protected Predicate determineLateralEmulationPredicate(TableGroup tableGroup) {
    if (tableGroup.getPrimaryTableReference() instanceof QueryPartTableReference) {
        final QueryPartTableReference tableReference = (QueryPartTableReference) tableGroup.getPrimaryTableReference();
        final List<String> columnNames = tableReference.getColumnNames();
        final List<ColumnReference> columnReferences = new ArrayList<>(columnNames.size());
        final List<ColumnReference> subColumnReferences = new ArrayList<>(columnNames.size());
        final QueryPart queryPart = tableReference.getQueryPart();
        for (String columnName : columnNames) {
            columnReferences.add(new ColumnReference(tableReference, columnName, false, null, null, null, sessionFactory));
        }
        // The following optimization only makes sense if the necessary features are supported natively
        if ((columnReferences.size() == 1 || supportsRowValueConstructorSyntax()) && supportsDistinctFromPredicate()) {
            // ... x(c) on x.c is not distinct from (... fetch first 1 rows only)
            if (queryPart.getFetchClauseType() == FetchClauseType.ROWS_ONLY && queryPart.getFetchClauseExpression() instanceof QueryLiteral<?> && Integer.valueOf(1).equals(((QueryLiteral<?>) queryPart.getFetchClauseExpression()).getLiteralValue())) {
                return new ComparisonPredicate(new SqlTuple(columnReferences, tableGroup.getModelPart()), ComparisonOperator.NOT_DISTINCT_FROM, queryPart);
            }
        }
        // ... x(c) on exists(select x.c intersect ...)
        if (supportsIntersect()) {
            final QuerySpec lhsReferencesQuery = new QuerySpec(false);
            for (ColumnReference columnReference : columnReferences) {
                lhsReferencesQuery.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, columnReference));
            }
            final List<QueryPart> queryParts = new ArrayList<>(2);
            queryParts.add(lhsReferencesQuery);
            queryParts.add(queryPart);
            return new ExistsPredicate(new QueryGroup(false, SetOperator.INTERSECT, queryParts), false, getBooleanType());
        }
        // Double nested sub-query rendering if nothing else works
        // We try to avoid this as much as possible as it is not very efficient and some DBs don't like it
        // when a correlation happens in a sub-query that is not a direct child
        // ... x(c) on exists(select 1 from (...) synth_(c) where x.c = synth_.c)
        final QueryPartTableGroup subTableGroup = new QueryPartTableGroup(tableGroup.getNavigablePath(), (TableGroupProducer) tableGroup.getModelPart(), queryPart, "synth_", columnNames, false, true, sessionFactory);
        for (String columnName : columnNames) {
            subColumnReferences.add(new ColumnReference(subTableGroup.getPrimaryTableReference(), columnName, false, null, null, null, sessionFactory));
        }
        final QuerySpec existsQuery = new QuerySpec(false, 1);
        existsQuery.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, new QueryLiteral<>(1, getIntegerType())));
        existsQuery.getFromClause().addRoot(subTableGroup);
        existsQuery.applyPredicate(new ComparisonPredicate(new SqlTuple(columnReferences, tableGroup.getModelPart()), ComparisonOperator.NOT_DISTINCT_FROM, new SqlTuple(subColumnReferences, tableGroup.getModelPart())));
        return new ExistsPredicate(existsQuery, false, getBooleanType());
    }
    return null;
}
Also used : QueryPart(org.hibernate.sql.ast.tree.select.QueryPart) ExistsPredicate(org.hibernate.sql.ast.tree.predicate.ExistsPredicate) ArrayList(java.util.ArrayList) QueryPartTableGroup(org.hibernate.sql.ast.tree.from.QueryPartTableGroup) ComparisonPredicate(org.hibernate.sql.ast.tree.predicate.ComparisonPredicate) QueryGroup(org.hibernate.sql.ast.tree.select.QueryGroup) ConvertedQueryLiteral(org.hibernate.sql.ast.tree.expression.ConvertedQueryLiteral) QueryLiteral(org.hibernate.sql.ast.tree.expression.QueryLiteral) SqlTuple(org.hibernate.sql.ast.tree.expression.SqlTuple) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) QueryPartTableReference(org.hibernate.sql.ast.tree.from.QueryPartTableReference) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference)

Example 20 with SqlSelectionImpl

use of org.hibernate.sql.results.internal.SqlSelectionImpl in project hibernate-orm by hibernate.

the class LoaderSelectBuilder method generateSubSelect.

private QueryPart generateSubSelect(PluralAttributeMapping attributeMapping, TableGroup rootTableGroup, SubselectFetch subselect, int jdbcTypeCount, LoaderSqlAstCreationState creationState, SessionFactoryImplementor sessionFactory) {
    final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor();
    final QuerySpec subQuery = new QuerySpec(false);
    final QuerySpec loadingSqlAst = subselect.getLoadingSqlAst();
    // todo (6.0) : we need to find the owner's TableGroup in the `loadingSqlAst`
    final TableGroup ownerTableGroup = subselect.getOwnerTableGroup();
    // transfer the from-clause
    loadingSqlAst.getFromClause().visitRoots(subQuery.getFromClause()::addRoot);
    final SqlExpressionResolver sqlExpressionResolver = creationState.getSqlExpressionResolver();
    final NavigablePath navigablePath = ownerTableGroup.getNavigablePath().append(attributeMapping.getAttributeName());
    fkDescriptor.visitTargetSelectables((valuesPosition, selection) -> {
        // for each column, resolve a SqlSelection and add it to the sub-query select-clause
        final TableReference tableReference = ownerTableGroup.resolveTableReference(navigablePath, selection.getContainingTableExpression());
        final Expression expression = sqlExpressionResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, selection.getSelectionExpression()), sqlAstProcessingState -> new ColumnReference(tableReference, selection, sessionFactory));
        subQuery.getSelectClause().addSqlSelection(new SqlSelectionImpl(valuesPosition + 1, valuesPosition, expression));
    });
    // transfer the restriction
    subQuery.applyPredicate(loadingSqlAst.getWhereClauseRestrictions());
    return subQuery;
}
Also used : TableReference(org.hibernate.sql.ast.tree.from.TableReference) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) PluralTableGroup(org.hibernate.sql.ast.tree.from.PluralTableGroup) NavigablePath(org.hibernate.query.spi.NavigablePath) EntityIdentifierNavigablePath(org.hibernate.query.sqm.spi.EntityIdentifierNavigablePath) SqlExpressionResolver(org.hibernate.sql.ast.spi.SqlExpressionResolver) Expression(org.hibernate.sql.ast.tree.expression.Expression) ForeignKeyDescriptor(org.hibernate.metamodel.mapping.ForeignKeyDescriptor) SimpleForeignKeyDescriptor(org.hibernate.metamodel.mapping.internal.SimpleForeignKeyDescriptor) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference)

Aggregations

SqlSelectionImpl (org.hibernate.sql.results.internal.SqlSelectionImpl)21 QuerySpec (org.hibernate.sql.ast.tree.select.QuerySpec)18 ColumnReference (org.hibernate.sql.ast.tree.expression.ColumnReference)15 TableGroup (org.hibernate.sql.ast.tree.from.TableGroup)14 Expression (org.hibernate.sql.ast.tree.expression.Expression)12 ArrayList (java.util.ArrayList)11 NavigablePath (org.hibernate.query.spi.NavigablePath)10 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)9 TableReference (org.hibernate.sql.ast.tree.from.TableReference)9 SqmExpression (org.hibernate.query.sqm.tree.expression.SqmExpression)8 NamedTableReference (org.hibernate.sql.ast.tree.from.NamedTableReference)8 MappingModelExpressible (org.hibernate.metamodel.mapping.MappingModelExpressible)7 QueryLiteral (org.hibernate.sql.ast.tree.expression.QueryLiteral)7 LinkedHashMap (java.util.LinkedHashMap)6 List (java.util.List)6 PluralAttributeMapping (org.hibernate.metamodel.mapping.PluralAttributeMapping)6 SelfRenderingFunctionSqlAstExpression (org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression)6 MultiTableSqmMutationConverter (org.hibernate.query.sqm.mutation.internal.MultiTableSqmMutationConverter)6 SqmParameter (org.hibernate.query.sqm.tree.expression.SqmParameter)6 BinaryArithmeticExpression (org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression)6