use of org.hibernate.sql.ast.tree.predicate.Predicate in project hibernate-orm by hibernate.
the class HypotheticalSetWindowEmulation method generateSqmOrderedSetAggregateFunctionExpression.
@Override
public <T> SelfRenderingSqmOrderedSetAggregateFunction<T> generateSqmOrderedSetAggregateFunctionExpression(List<? extends SqmTypedNode<?>> arguments, SqmPredicate filter, SqmOrderByClause withinGroupClause, ReturnableType<T> impliedResultType, QueryEngine queryEngine, TypeConfiguration typeConfiguration) {
return new SelfRenderingSqmOrderedSetAggregateFunction<>(this, this, arguments, filter, withinGroupClause, impliedResultType, getArgumentsValidator(), getReturnTypeResolver(), queryEngine.getCriteriaBuilder(), getName()) {
@Override
public Expression convertToSqlAst(SqmToSqlAstConverter walker) {
final Clause currentClause = walker.getCurrentClauseStack().getCurrent();
if (currentClause == Clause.OVER) {
return super.convertToSqlAst(walker);
} else if (currentClause != Clause.SELECT) {
throw new IllegalArgumentException("Can't emulate [" + getName() + "] in clause " + currentClause + ". Only the SELECT clause is supported!");
}
final ReturnableType<?> resultType = resolveResultType(walker.getCreationContext().getMappingMetamodel().getTypeConfiguration());
List<SqlAstNode> arguments = resolveSqlAstArguments(getArguments(), walker);
ArgumentsValidator argumentsValidator = getArgumentsValidator();
if (argumentsValidator != null) {
argumentsValidator.validateSqlTypes(arguments, getFunctionName());
}
List<SortSpecification> withinGroup;
if (this.getWithinGroup() == null) {
withinGroup = Collections.emptyList();
} else {
walker.getCurrentClauseStack().push(Clause.ORDER);
try {
final List<SqmSortSpecification> sortSpecifications = this.getWithinGroup().getSortSpecifications();
withinGroup = new ArrayList<>(sortSpecifications.size());
for (SqmSortSpecification sortSpecification : sortSpecifications) {
final SortSpecification specification = (SortSpecification) walker.visitSortSpecification(sortSpecification);
if (specification != null) {
withinGroup.add(specification);
}
}
} finally {
walker.getCurrentClauseStack().pop();
}
}
final SelfRenderingFunctionSqlAstExpression function = new SelfRenderingOrderedSetAggregateFunctionSqlAstExpression(getFunctionName(), getRenderingSupport(), Collections.emptyList(), getFilter() == null ? null : (Predicate) getFilter().accept(walker), Collections.emptyList(), resultType, getMappingModelExpressible(walker, resultType));
final Over<Object> windowFunction = new Over<>(function, new ArrayList<>(), withinGroup);
walker.registerQueryTransformer(new AggregateWindowEmulationQueryTransformer(windowFunction, withinGroup, arguments));
return windowFunction;
}
};
}
use of org.hibernate.sql.ast.tree.predicate.Predicate in project hibernate-orm by hibernate.
the class SybaseASESqlAstTranslator method renderTableGroupJoin.
@Override
protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List<TableGroupJoin> tableGroupJoinCollector) {
if (tableGroupJoin.getJoinType() == SqlAstJoinType.CROSS) {
appendSql(", ");
} else {
appendSql(WHITESPACE);
appendSql(tableGroupJoin.getJoinType().getText());
appendSql("join ");
}
final Predicate predicate;
if (tableGroupJoin.getPredicate() == null) {
if (tableGroupJoin.getJoinType() == SqlAstJoinType.CROSS) {
predicate = null;
} else {
predicate = new BooleanExpressionPredicate(new QueryLiteral<>(true, getBooleanType()));
}
} else {
predicate = tableGroupJoin.getPredicate();
}
if (predicate != null && !predicate.isEmpty()) {
renderTableGroup(tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector);
} else {
renderTableGroup(tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector);
}
}
use of org.hibernate.sql.ast.tree.predicate.Predicate 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;
}
use of org.hibernate.sql.ast.tree.predicate.Predicate 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;
}
use of org.hibernate.sql.ast.tree.predicate.Predicate in project hibernate-orm by hibernate.
the class AbstractSqlAstTranslator method emulateFetchOffsetWithWindowFunctions.
protected void emulateFetchOffsetWithWindowFunctions(QueryPart queryPart, Expression offsetExpression, Expression fetchExpression, FetchClauseType fetchClauseType, boolean emulateFetchClause) {
final QueryPart queryPartForRowNumbering = this.queryPartForRowNumbering;
final int queryPartForRowNumberingClauseDepth = this.queryPartForRowNumberingClauseDepth;
final boolean needsSelectAliases = this.needsSelectAliases;
try {
this.queryPartForRowNumbering = queryPart;
this.queryPartForRowNumberingClauseDepth = clauseStack.depth();
this.needsSelectAliases = true;
final String alias = "r_" + queryPartForRowNumberingAliasCounter + '_';
queryPartForRowNumberingAliasCounter++;
final boolean needsParenthesis;
if (queryPart instanceof QueryGroup) {
// We always need query wrapping if we are in a query group and the query part has a fetch clause
needsParenthesis = queryPart.hasOffsetOrFetchClause();
} else {
needsParenthesis = !queryPart.isRoot();
}
if (needsParenthesis && !queryPart.isRoot()) {
appendSql(OPEN_PARENTHESIS);
}
appendSql("select ");
if (getClauseStack().isEmpty()) {
appendSql('*');
} else {
final int size = queryPart.getFirstQuerySpec().getSelectClause().getSqlSelections().size();
String separator = "";
for (int i = 0; i < size; i++) {
appendSql(separator);
appendSql(alias);
appendSql(".c");
appendSql(i);
separator = COMA_SEPARATOR;
}
}
appendSql(" from ");
if (!needsParenthesis || queryPart.isRoot()) {
appendSql(OPEN_PARENTHESIS);
}
queryPart.accept(this);
if (!needsParenthesis || queryPart.isRoot()) {
appendSql(CLOSE_PARENTHESIS);
}
appendSql(WHITESPACE);
appendSql(alias);
appendSql(" where ");
final Stack<Clause> clauseStack = getClauseStack();
clauseStack.push(Clause.WHERE);
try {
if (emulateFetchClause && fetchExpression != null) {
switch(fetchClauseType) {
case PERCENT_ONLY:
appendSql(alias);
appendSql(".rn<=");
if (offsetExpression != null) {
offsetExpression.accept(this);
appendSql('+');
}
appendSql("ceil(");
appendSql(alias);
appendSql(".cnt*");
fetchExpression.accept(this);
appendSql("/100)");
break;
case ROWS_ONLY:
appendSql(alias);
appendSql(".rn<=");
if (offsetExpression != null) {
offsetExpression.accept(this);
appendSql('+');
}
fetchExpression.accept(this);
break;
case PERCENT_WITH_TIES:
appendSql(alias);
appendSql(".rnk<=");
if (offsetExpression != null) {
offsetExpression.accept(this);
appendSql('+');
}
appendSql("ceil(");
appendSql(alias);
appendSql(".cnt*");
fetchExpression.accept(this);
appendSql("/100)");
break;
case ROWS_WITH_TIES:
appendSql(alias);
appendSql(".rnk<=");
if (offsetExpression != null) {
offsetExpression.accept(this);
appendSql('+');
}
fetchExpression.accept(this);
break;
}
}
// todo: not sure if databases handle order by row number or the original ordering better..
if (offsetExpression == null) {
final Predicate additionalWherePredicate = this.additionalWherePredicate;
if (additionalWherePredicate != null && !additionalWherePredicate.isEmpty()) {
this.additionalWherePredicate = null;
appendSql(" and ");
additionalWherePredicate.accept(this);
}
if (queryPart.isRoot()) {
switch(fetchClauseType) {
case PERCENT_ONLY:
case ROWS_ONLY:
appendSql(" order by ");
appendSql(alias);
appendSql(".rn");
break;
case PERCENT_WITH_TIES:
case ROWS_WITH_TIES:
appendSql(" order by ");
appendSql(alias);
appendSql(".rnk");
break;
}
}
} else {
if (emulateFetchClause && fetchExpression != null) {
appendSql(" and ");
}
appendSql(alias);
appendSql(".rn>");
offsetExpression.accept(this);
final Predicate additionalWherePredicate = this.additionalWherePredicate;
if (additionalWherePredicate != null && !additionalWherePredicate.isEmpty()) {
this.additionalWherePredicate = null;
appendSql(" and ");
additionalWherePredicate.accept(this);
}
if (queryPart.isRoot()) {
appendSql(" order by ");
appendSql(alias);
appendSql(".rn");
}
}
// We render the FOR UPDATE clause in the outer query
if (queryPart instanceof QuerySpec) {
clauseStack.pop();
clauseStack.push(Clause.FOR_UPDATE);
visitForUpdateClause((QuerySpec) queryPart);
}
} finally {
clauseStack.pop();
}
if (needsParenthesis && !queryPart.isRoot()) {
appendSql(CLOSE_PARENTHESIS);
}
} finally {
this.queryPartForRowNumbering = queryPartForRowNumbering;
this.queryPartForRowNumberingClauseDepth = queryPartForRowNumberingClauseDepth;
this.needsSelectAliases = needsSelectAliases;
}
}
Aggregations