hibernate/hibernate-orm · error · IllegalArgumentException
Can't emulate [%s] in clause %s. Only the SELECT clause is s
Error message
Can't emulate [%s] in clause %s. Only the SELECT clause is supported
What it means
InverseDistributionWindowEmulation inlines an inverse distribution function (percentile_cont/disc) as a scalar subquery on dialects without native support. The emulation can only be placed in the SELECT clause or an OVER window; any other current clause (WHERE, GROUP BY, HAVING, ORDER BY) throws IllegalArgumentException at SQM-to-SQL conversion.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/dialect/function/InverseDistributionWindowEmulation.java:66
SqmOrderByClause withinGroupClause,
ReturnableType<T> impliedResultType,
QueryEngine queryEngine) {
return new SelfRenderingInverseDistributionFunction<>(
arguments,
filter,
withinGroupClause,
impliedResultType,
queryEngine
) {
@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 );
final List<SqlAstNode> arguments = resolveSqlAstArguments( getArguments(), walker );
final ArgumentsValidator argumentsValidator = getArgumentsValidator();
if ( argumentsValidator != null ) {
argumentsValidator.validateSqlTypes( arguments, getFunctionName() );
}
final 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 ) {View on GitHub (pinned to fad1729dce)
Solutions
- Compute the function in an inner SELECT with an alias and reference the alias in the outer clause
- Restrict the function to the SELECT list
- Use native SQL or a dialect with native ordered-set aggregate support
Example fix
// before select e.dept, percentile_disc(0.5) within group (order by e.salary) from Emp e group by e.dept order by percentile_disc(0.5) within group (order by e.salary) // after select d.dept, d.p50 from ( select e.dept as dept, percentile_disc(0.5) within group (order by e.salary) as p50 from Emp e group by e.dept ) d order by d.p50
Defensive patterns
Strategy: fallback
Validate before calling
// Reject percentile_ references outside the SELECT list before touching the database
static boolean selectListOnly(String hql) {
String lower = hql.toLowerCase(java.util.Locale.ROOT);
for (String kw : new String[]{" order by ", " where ", " group by ", " having "}) {
int kwAt = lower.indexOf(kw);
if (kwAt >= 0 && lower.indexOf("percentile_", kwAt) >= 0) return false;
}
return true;
} Try / catch
try {
return em.createQuery(hql, Double.class).getResultList();
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("Only the SELECT clause is supported")) {
return em.createQuery(wrapInSubquery(hql), Double.class).getResultList();
}
throw e;
} Prevention
- Reference computed percentiles by alias from an outer query
- Keep emulated window/ordered-set functions out of WHERE/ORDER BY/GROUP BY/HAVING
- Add CI runs on emulation dialects for percentile-based queries
When it happens
Trigger: HQL that references percentile_cont(...)/percentile_disc(...) inside ORDER BY, WHERE, GROUP BY or HAVING on an emulation dialect (typical MySQL family).
Common situations: Sorting by a percentile; reusing a SELECT-list expression in ORDER BY during refactoring instead of an alias; portable queries run against multiple dialects where only some emulate.
Related errors
- Can't emulate [%s] in clause %s. Only the SELECT clause is s
- Can't emulate filter clause for inverse distribution functio
- Could not resolve sort expression: '${sortExpression}'
- The function {name} is not a window function
- Insert conflict 'do update' clause with constraint name is n
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/46f5610be317f0b3.
Report an issue: GitHub.