use of org.hibernate.sql.ast.tree.select.QuerySpec in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitPluralAttributeSizeFunction.
@Override
public Expression visitPluralAttributeSizeFunction(SqmCollectionSize function) {
final SqmPath<?> pluralPath = function.getPluralPath();
prepareReusablePath(pluralPath, () -> null);
final TableGroup parentTableGroup = getFromClauseAccess().getTableGroup(pluralPath.getNavigablePath().getParent());
assert parentTableGroup != null;
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) parentTableGroup.getModelPart().findSubPart(pluralPath.getNavigablePath().getUnaliasedLocalName(), null);
assert pluralAttributeMapping != null;
final QuerySpec subQuerySpec = new QuerySpec(false);
pushProcessingState(new SqlAstQueryPartProcessingStateImpl(subQuerySpec, getCurrentProcessingState(), this, currentClauseStack::getCurrent, false));
try {
final TableGroup tableGroup = pluralAttributeMapping.createRootTableGroup(true, pluralPath.getNavigablePath(), null, () -> subQuerySpec::applyPredicate, this, creationContext);
pluralAttributeMapping.applyBaseRestrictions(subQuerySpec::applyPredicate, tableGroup, true, getLoadQueryInfluencers().getEnabledFilters(), null, this);
getFromClauseAccess().registerTableGroup(pluralPath.getNavigablePath(), tableGroup);
registerPluralTableGroupParts(tableGroup);
subQuerySpec.getFromClause().addRoot(tableGroup);
final AbstractSqmSelfRenderingFunctionDescriptor functionDescriptor = (AbstractSqmSelfRenderingFunctionDescriptor) creationContext.getSessionFactory().getQueryEngine().getSqmFunctionRegistry().findFunctionDescriptor("count");
final BasicType<Integer> integerType = creationContext.getMappingMetamodel().getTypeConfiguration().getBasicTypeForJavaType(Integer.class);
final Expression expression = new SelfRenderingAggregateFunctionSqlAstExpression(functionDescriptor.getName(), functionDescriptor, Collections.singletonList(new QueryLiteral<>(1, integerType)), null, integerType, integerType);
subQuerySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, expression));
subQuerySpec.applyPredicate(pluralAttributeMapping.getKeyDescriptor().generateJoinPredicate(parentTableGroup, tableGroup, getSqlExpressionResolver(), creationContext));
} finally {
popProcessingStateStack();
}
return subQuerySpec;
}
use of org.hibernate.sql.ast.tree.select.QuerySpec in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method createCorrelatedAggregateSubQuery.
protected Expression createCorrelatedAggregateSubQuery(AbstractSqmSpecificPluralPartPath<?> pluralPartPath, boolean index, String function) {
prepareReusablePath(pluralPartPath.getLhs(), () -> null);
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) determineValueMapping(pluralPartPath.getPluralDomainPath());
final FromClauseAccess parentFromClauseAccess = getFromClauseAccess();
final QuerySpec subQuerySpec = new QuerySpec(false);
pushProcessingState(new SqlAstQueryPartProcessingStateImpl(subQuerySpec, getCurrentProcessingState(), this, currentClauseStack::getCurrent, false));
try {
final TableGroup tableGroup = pluralAttributeMapping.createRootTableGroup(true, pluralPartPath.getNavigablePath(), null, () -> subQuerySpec::applyPredicate, this, creationContext);
pluralAttributeMapping.applyBaseRestrictions(subQuerySpec::applyPredicate, tableGroup, true, getLoadQueryInfluencers().getEnabledFilters(), null, this);
getFromClauseAccess().registerTableGroup(pluralPartPath.getNavigablePath(), tableGroup);
registerPluralTableGroupParts(tableGroup);
subQuerySpec.getFromClause().addRoot(tableGroup);
final AbstractSqmSelfRenderingFunctionDescriptor functionDescriptor = (AbstractSqmSelfRenderingFunctionDescriptor) creationContext.getSessionFactory().getQueryEngine().getSqmFunctionRegistry().findFunctionDescriptor(function);
final CollectionPart collectionPart = index ? pluralAttributeMapping.getIndexDescriptor() : pluralAttributeMapping.getElementDescriptor();
final ModelPart modelPart;
if (collectionPart instanceof EntityAssociationMapping) {
modelPart = ((EntityAssociationMapping) collectionPart).getKeyTargetMatchPart();
} else {
modelPart = collectionPart;
}
final List<Expression> arguments = new ArrayList<>(1);
final NavigablePath navigablePath = pluralPartPath.getNavigablePath();
final int jdbcTypeCount = modelPart.getJdbcTypeCount();
final List<Expression> tupleElements;
if (jdbcTypeCount == 1) {
tupleElements = arguments;
} else {
tupleElements = new ArrayList<>(jdbcTypeCount);
}
modelPart.forEachSelectable((selectionIndex, selectionMapping) -> tupleElements.add(new ColumnReference(tableGroup.resolveTableReference(navigablePath, selectionMapping.getContainingTableExpression()), selectionMapping, creationContext.getSessionFactory())));
if (jdbcTypeCount != 1) {
arguments.add(new SqlTuple(tupleElements, modelPart));
}
final Expression expression = new SelfRenderingAggregateFunctionSqlAstExpression(functionDescriptor.getName(), functionDescriptor, arguments, null, (ReturnableType<?>) functionDescriptor.getReturnTypeResolver().resolveFunctionReturnType(() -> null, arguments).getJdbcMapping(), modelPart);
subQuerySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, expression));
NavigablePath parent = pluralPartPath.getPluralDomainPath().getNavigablePath().getParent();
subQuerySpec.applyPredicate(pluralAttributeMapping.getKeyDescriptor().generateJoinPredicate(parentFromClauseAccess.findTableGroup(parent), tableGroup, getSqlExpressionResolver(), creationContext));
} finally {
popProcessingStateStack();
}
return subQuerySpec;
}
use of org.hibernate.sql.ast.tree.select.QuerySpec in project hibernate-orm by hibernate.
the class RestrictedDeleteExecutionDelegate method executeWithoutIdTable.
private int executeWithoutIdTable(Predicate suppliedPredicate, TableGroup tableGroup, Map<SqmParameter<?>, List<List<JdbcParameter>>> restrictionSqmParameterResolutions, Map<SqmParameter<?>, MappingModelExpressible<?>> paramTypeResolutions, SqlExpressionResolver sqlExpressionResolver, ExecutionContext executionContext) {
assert entityDescriptor == entityDescriptor.getRootEntityDescriptor();
final EntityPersister rootEntityPersister = entityDescriptor.getEntityPersister();
final String rootTableName = ((Joinable) rootEntityPersister).getTableName();
final NamedTableReference rootTableReference = (NamedTableReference) tableGroup.resolveTableReference(tableGroup.getNavigablePath(), rootTableName);
final QuerySpec matchingIdSubQuerySpec = ExecuteWithoutIdTableHelper.createIdMatchingSubQuerySpec(tableGroup.getNavigablePath(), rootTableReference, suppliedPredicate, rootEntityPersister, sqlExpressionResolver, sessionFactory);
final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(executionContext.getQueryParameterBindings(), domainParameterXref, SqmUtil.generateJdbcParamsXref(domainParameterXref, () -> restrictionSqmParameterResolutions), sessionFactory.getRuntimeMetamodels().getMappingMetamodel(), navigablePath -> tableGroup, new SqmParameterMappingModelResolutionAccess() {
@Override
@SuppressWarnings("unchecked")
public <T> MappingModelExpressible<T> getResolvedMappingModelType(SqmParameter<T> parameter) {
return (MappingModelExpressible<T>) paramTypeResolutions.get(parameter);
}
}, executionContext.getSession());
SqmMutationStrategyHelper.cleanUpCollectionTables(entityDescriptor, (tableReference, attributeMapping) -> {
// No need for a predicate if there is no supplied predicate i.e. this is a full cleanup
if (suppliedPredicate == null) {
return null;
}
final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor();
final QuerySpec idSelectFkSubQuery;
// todo (6.0): based on the location of the attribute mapping, we could prune the table group of the subquery
if (fkDescriptor.getTargetPart() instanceof EntityIdentifierMapping) {
idSelectFkSubQuery = matchingIdSubQuerySpec;
} else {
idSelectFkSubQuery = ExecuteWithoutIdTableHelper.createIdMatchingSubQuerySpec(tableGroup.getNavigablePath(), rootTableReference, suppliedPredicate, rootEntityPersister, sqlExpressionResolver, sessionFactory);
}
return new InSubQueryPredicate(MappingModelHelper.buildColumnReferenceExpression(fkDescriptor, null, sessionFactory), idSelectFkSubQuery, false);
}, jdbcParameterBindings, executionContext);
if (rootTableReference instanceof UnionTableReference) {
final MutableInteger rows = new MutableInteger();
entityDescriptor.visitConstraintOrderedTables((tableExpression, tableKeyColumnVisitationSupplier) -> {
final NamedTableReference tableReference = new NamedTableReference(tableExpression, tableGroup.getPrimaryTableReference().getIdentificationVariable(), false, sessionFactory);
final QuerySpec idMatchingSubQuerySpec;
// No need for a predicate if there is no supplied predicate i.e. this is a full cleanup
if (suppliedPredicate == null) {
idMatchingSubQuerySpec = null;
} else {
idMatchingSubQuerySpec = matchingIdSubQuerySpec;
}
rows.plus(deleteFromNonRootTableWithoutIdTable(tableReference, tableKeyColumnVisitationSupplier, sqlExpressionResolver, tableGroup, idMatchingSubQuerySpec, jdbcParameterBindings, executionContext));
});
return rows.get();
} else {
entityDescriptor.visitConstraintOrderedTables((tableExpression, tableKeyColumnVisitationSupplier) -> {
if (!tableExpression.equals(rootTableName)) {
final NamedTableReference tableReference = (NamedTableReference) tableGroup.getTableReference(tableGroup.getNavigablePath(), tableExpression, true, true);
final QuerySpec idMatchingSubQuerySpec;
// No need for a predicate if there is no supplied predicate i.e. this is a full cleanup
if (suppliedPredicate == null) {
idMatchingSubQuerySpec = null;
} else {
idMatchingSubQuerySpec = matchingIdSubQuerySpec;
}
deleteFromNonRootTableWithoutIdTable(tableReference, tableKeyColumnVisitationSupplier, sqlExpressionResolver, tableGroup, idMatchingSubQuerySpec, jdbcParameterBindings, executionContext);
}
});
return deleteFromRootTableWithoutIdTable(rootTableReference, suppliedPredicate, jdbcParameterBindings, executionContext);
}
}
use of org.hibernate.sql.ast.tree.select.QuerySpec in project hibernate-orm by hibernate.
the class RestrictedDeleteExecutionDelegate method executeUsingIdTable.
private int executeUsingIdTable(Predicate predicate, ExecutionContext executionContext, JdbcParameterBindings jdbcParameterBindings) {
final int rows = ExecuteWithTemporaryTableHelper.saveMatchingIdsIntoIdTable(converter, predicate, idTable, sessionUidAccess, jdbcParameterBindings, executionContext);
final QuerySpec idTableIdentifierSubQuery = ExecuteWithTemporaryTableHelper.createIdTableSelectQuerySpec(idTable, sessionUidAccess, entityDescriptor, executionContext);
SqmMutationStrategyHelper.cleanUpCollectionTables(entityDescriptor, (tableReference, attributeMapping) -> {
final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor();
final QuerySpec idTableFkSubQuery;
if (fkDescriptor.getTargetPart() instanceof EntityIdentifierMapping) {
idTableFkSubQuery = idTableIdentifierSubQuery;
} else {
idTableFkSubQuery = ExecuteWithTemporaryTableHelper.createIdTableSelectQuerySpec(idTable, fkDescriptor.getTargetPart(), sessionUidAccess, entityDescriptor, executionContext);
}
return new InSubQueryPredicate(MappingModelHelper.buildColumnReferenceExpression(fkDescriptor, null, sessionFactory), idTableFkSubQuery, false);
}, JdbcParameterBindings.NO_BINDINGS, executionContext);
entityDescriptor.visitConstraintOrderedTables((tableExpression, tableKeyColumnVisitationSupplier) -> deleteFromTableUsingIdTable(tableExpression, tableKeyColumnVisitationSupplier, idTableIdentifierSubQuery, executionContext));
return rows;
}
use of org.hibernate.sql.ast.tree.select.QuerySpec in project hibernate-orm by hibernate.
the class OracleSqlAstTranslator method emulateFetchOffsetWithWindowFunctions.
@Override
protected void emulateFetchOffsetWithWindowFunctions(QueryPart queryPart, Expression offsetExpression, Expression fetchExpression, FetchClauseType fetchClauseType, boolean emulateFetchClause) {
if (queryPart instanceof QuerySpec && offsetExpression == null && fetchClauseType == FetchClauseType.ROWS_ONLY) {
// Special case for Oracle to support locking along with simple max results paging
final QuerySpec querySpec = (QuerySpec) queryPart;
withRowNumbering(querySpec, // we need select aliases to avoid ORA-00918: column ambiguously defined
true, () -> {
final QueryPart currentQueryPart = getQueryPartStack().getCurrent();
final boolean needsParenthesis;
final boolean needsWrapper;
if (currentQueryPart instanceof QueryGroup) {
needsParenthesis = false;
// visitQuerySpec will add the select wrapper
needsWrapper = !currentQueryPart.hasOffsetOrFetchClause();
} else {
needsParenthesis = !querySpec.isRoot();
needsWrapper = true;
}
if (needsWrapper) {
if (needsParenthesis) {
appendSql('(');
}
appendSql("select * from ");
if (!needsParenthesis) {
appendSql('(');
}
}
super.visitQuerySpec(querySpec);
if (needsWrapper) {
if (!needsParenthesis) {
appendSql(')');
}
}
appendSql(" where rownum<=");
final Stack<Clause> clauseStack = getClauseStack();
clauseStack.push(Clause.WHERE);
try {
fetchExpression.accept(this);
// We render the FOR UPDATE clause in the outer query
clauseStack.pop();
clauseStack.push(Clause.FOR_UPDATE);
visitForUpdateClause(querySpec);
} finally {
clauseStack.pop();
}
if (needsWrapper) {
if (needsParenthesis) {
appendSql(')');
}
}
});
} else {
super.emulateFetchOffsetWithWindowFunctions(queryPart, offsetExpression, fetchExpression, fetchClauseType, emulateFetchClause);
}
}
Aggregations