Search in sources :

Example 81 with Expression

use of org.hibernate.sql.ast.tree.expression.Expression 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 82 with Expression

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

the class ArgumentTypesValidator method validateSqlTypes.

/**
 * This is the final validation phase with the fully-typed SQL nodes. Note that these
 * checks are much less useful, occurring "too late", right before we execute the
 * query and get an error from the database. However, they help in the sense of (a)
 * resulting in more consistent/understandable error messages, and (b) protecting the
 * user from writing queries that depend on generally-unportable implicit type
 * conversions happening at the database level. (Implicit type conversions between
 * numeric types are portable, and are not prohibited here.)
 */
@Override
public void validateSqlTypes(List<? extends SqlAstNode> arguments, String functionName) {
    int count = 0;
    for (SqlAstNode argument : arguments) {
        if (argument instanceof Expression) {
            JdbcMappingContainer expressionType = ((Expression) argument).getExpressionType();
            if (expressionType != null) {
                ParameterDetector detector = new ParameterDetector();
                argument.accept(detector);
                if (detector.detected) {
                    count += expressionType.getJdbcTypeCount();
                } else {
                    count = validateArgument(count, expressionType, functionName);
                }
            }
        }
    }
}
Also used : JdbcMappingContainer(org.hibernate.metamodel.mapping.JdbcMappingContainer) Expression(org.hibernate.sql.ast.tree.expression.Expression) SqlAstNode(org.hibernate.sql.ast.tree.SqlAstNode)

Example 83 with Expression

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

the class RestrictedDeleteExecutionDelegate method deleteFromNonRootTableWithoutIdTable.

private int deleteFromNonRootTableWithoutIdTable(NamedTableReference targetTableReference, Supplier<Consumer<SelectableConsumer>> tableKeyColumnVisitationSupplier, SqlExpressionResolver sqlExpressionResolver, TableGroup rootTableGroup, QuerySpec matchingIdSubQuerySpec, JdbcParameterBindings jdbcParameterBindings, ExecutionContext executionContext) {
    assert targetTableReference != null;
    log.tracef("deleteFromNonRootTable - %s", targetTableReference.getTableExpression());
    final NamedTableReference deleteTableReference = new NamedTableReference(targetTableReference.getTableExpression(), DeleteStatement.DEFAULT_ALIAS, true, sessionFactory);
    final Predicate tableDeletePredicate;
    if (matchingIdSubQuerySpec == null) {
        tableDeletePredicate = null;
    } else {
        /*
			 * delete from sub_table
			 * where sub_id in (
			 * 		select root_id from root_table
			 * 		where {predicate}
			 * )
			 */
        /*
			 * Create the `sub_id` reference as the LHS of the in-subquery predicate
			 */
        final List<ColumnReference> deletingTableColumnRefs = new ArrayList<>();
        tableKeyColumnVisitationSupplier.get().accept((columnIndex, selection) -> {
            assert deleteTableReference.getTableReference(selection.getContainingTableExpression()) != null;
            final Expression expression = sqlExpressionResolver.resolveSqlExpression(SqlExpressionResolver.createColumnReferenceKey(deleteTableReference, selection.getSelectionExpression()), sqlAstProcessingState -> new ColumnReference(deleteTableReference, selection, sessionFactory));
            deletingTableColumnRefs.add((ColumnReference) expression);
        });
        final Expression deletingTableColumnRefsExpression;
        if (deletingTableColumnRefs.size() == 1) {
            deletingTableColumnRefsExpression = deletingTableColumnRefs.get(0);
        } else {
            deletingTableColumnRefsExpression = new SqlTuple(deletingTableColumnRefs, entityDescriptor.getIdentifierMapping());
        }
        tableDeletePredicate = new InSubQueryPredicate(deletingTableColumnRefsExpression, matchingIdSubQuerySpec, false);
    }
    final DeleteStatement sqlAstDelete = new DeleteStatement(deleteTableReference, tableDeletePredicate);
    final int rows = executeSqlDelete(sqlAstDelete, jdbcParameterBindings, executionContext);
    log.debugf("deleteFromNonRootTable - `%s` : %s rows", targetTableReference, rows);
    return rows;
}
Also used : NamedTableReference(org.hibernate.sql.ast.tree.from.NamedTableReference) Expression(org.hibernate.sql.ast.tree.expression.Expression) InSubQueryPredicate(org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate) ArrayList(java.util.ArrayList) SqlTuple(org.hibernate.sql.ast.tree.expression.SqlTuple) SqmDeleteStatement(org.hibernate.query.sqm.tree.delete.SqmDeleteStatement) DeleteStatement(org.hibernate.sql.ast.tree.delete.DeleteStatement) InSubQueryPredicate(org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate) Predicate(org.hibernate.sql.ast.tree.predicate.Predicate) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference)

Example 84 with Expression

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

the class AbstractSqlAstTranslator method visitValuesList.

protected void visitValuesList(List<Values> valuesList) {
    appendSql("values");
    boolean firstTuple = true;
    final Stack<Clause> clauseStack = getClauseStack();
    try {
        clauseStack.push(Clause.VALUES);
        for (Values values : valuesList) {
            if (firstTuple) {
                firstTuple = false;
            } else {
                appendSql(COMA_SEPARATOR_CHAR);
            }
            appendSql(" (");
            boolean firstExpr = true;
            for (Expression expression : values.getExpressions()) {
                if (firstExpr) {
                    firstExpr = false;
                } else {
                    appendSql(COMA_SEPARATOR_CHAR);
                }
                expression.accept(this);
            }
            appendSql(')');
        }
    } finally {
        clauseStack.pop();
    }
}
Also used : Expression(org.hibernate.sql.ast.tree.expression.Expression) BinaryArithmeticExpression(org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression) SelfRenderingExpression(org.hibernate.sql.ast.tree.expression.SelfRenderingExpression) OrderedSetAggregateFunctionExpression(org.hibernate.sql.ast.tree.expression.OrderedSetAggregateFunctionExpression) CaseSimpleExpression(org.hibernate.sql.ast.tree.expression.CaseSimpleExpression) SqlSelectionExpression(org.hibernate.sql.ast.tree.expression.SqlSelectionExpression) CaseSearchedExpression(org.hibernate.sql.ast.tree.expression.CaseSearchedExpression) ModifiedSubQueryExpression(org.hibernate.sql.ast.tree.expression.ModifiedSubQueryExpression) Values(org.hibernate.sql.ast.tree.insert.Values) Clause(org.hibernate.sql.ast.Clause) FromClause(org.hibernate.sql.ast.tree.from.FromClause) SelectClause(org.hibernate.sql.ast.tree.select.SelectClause)

Example 85 with Expression

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

the class AbstractSqlAstTranslator method areAllResultsParameters.

protected boolean areAllResultsParameters(CaseSearchedExpression caseSearchedExpression) {
    final List<CaseSearchedExpression.WhenFragment> whenFragments = caseSearchedExpression.getWhenFragments();
    final Expression firstResult = whenFragments.get(0).getResult();
    if (isParameter(firstResult)) {
        for (int i = 1; i < whenFragments.size(); i++) {
            if (!isParameter(whenFragments.get(i).getResult())) {
                return false;
            }
        }
        return true;
    }
    return false;
}
Also used : Expression(org.hibernate.sql.ast.tree.expression.Expression) BinaryArithmeticExpression(org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression) SelfRenderingExpression(org.hibernate.sql.ast.tree.expression.SelfRenderingExpression) OrderedSetAggregateFunctionExpression(org.hibernate.sql.ast.tree.expression.OrderedSetAggregateFunctionExpression) CaseSimpleExpression(org.hibernate.sql.ast.tree.expression.CaseSimpleExpression) SqlSelectionExpression(org.hibernate.sql.ast.tree.expression.SqlSelectionExpression) CaseSearchedExpression(org.hibernate.sql.ast.tree.expression.CaseSearchedExpression) ModifiedSubQueryExpression(org.hibernate.sql.ast.tree.expression.ModifiedSubQueryExpression)

Aggregations

Expression (org.hibernate.sql.ast.tree.expression.Expression)130 CaseSearchedExpression (org.hibernate.sql.ast.tree.expression.CaseSearchedExpression)68 CaseSimpleExpression (org.hibernate.sql.ast.tree.expression.CaseSimpleExpression)67 BinaryArithmeticExpression (org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression)62 SqlSelectionExpression (org.hibernate.sql.ast.tree.expression.SqlSelectionExpression)57 ModifiedSubQueryExpression (org.hibernate.sql.ast.tree.expression.ModifiedSubQueryExpression)54 SelfRenderingExpression (org.hibernate.sql.ast.tree.expression.SelfRenderingExpression)54 ColumnReference (org.hibernate.sql.ast.tree.expression.ColumnReference)42 SelfRenderingFunctionSqlAstExpression (org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression)37 SqlTuple (org.hibernate.sql.ast.tree.expression.SqlTuple)35 SqmExpression (org.hibernate.query.sqm.tree.expression.SqmExpression)34 SelfRenderingSqlFragmentExpression (org.hibernate.sql.ast.tree.expression.SelfRenderingSqlFragmentExpression)33 SelfRenderingAggregateFunctionSqlAstExpression (org.hibernate.query.sqm.function.SelfRenderingAggregateFunctionSqlAstExpression)32 ArrayList (java.util.ArrayList)31 SqmModifiedSubQueryExpression (org.hibernate.query.sqm.tree.expression.SqmModifiedSubQueryExpression)31 TableGroup (org.hibernate.sql.ast.tree.from.TableGroup)28 TableReference (org.hibernate.sql.ast.tree.from.TableReference)25 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)23 ComparisonPredicate (org.hibernate.sql.ast.tree.predicate.ComparisonPredicate)23 NavigablePath (org.hibernate.query.spi.NavigablePath)21