{"record":{"id":"6ebcd83d9f82b80b","repo":"hibernate/hibernate-orm","slug":"can-t-emulate-filter-clause-for-inverse-distributi-6ebcd8","errorCode":null,"errorMessage":"Can't emulate filter clause for inverse distribution function [%s]","messagePattern":"Can't emulate filter clause for inverse distribution function \\[(.+?)\\]","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/dialect/function/InverseDistributionFunction.java","lineNumber":99,"sourceCode":"\tpublic void render(\n\t\t\tSqlAppender sqlAppender,\n\t\t\tList<? extends SqlAstNode> sqlAstArguments,\n\t\t\tPredicate filter,\n\t\t\tReturnableType<?> returnType,\n\t\t\tSqlAstTranslator<?> walker) {\n\t\trender( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), returnType, walker );\n\t}\n\n\t@Override\n\tpublic void render(\n\t\t\tSqlAppender sqlAppender,\n\t\t\tList<? extends SqlAstNode> sqlAstArguments,\n\t\t\tPredicate filter,\n\t\t\tList<SortSpecification> withinGroup,\n\t\t\tReturnableType<?> returnType,\n\t\t\tSqlAstTranslator<?> translator) {\n\t\tif ( filter != null && !filterClauseSupported( translator ) ) {\n\t\t\tthrow new IllegalArgumentException( \"Can't emulate filter clause for inverse distribution function [\" + getName() + \"]\" );\n\t\t}\n\t\tsqlAppender.appendSql( getName() );\n\t\tsqlAppender.appendSql( '(' );\n\t\tif ( !sqlAstArguments.isEmpty() ) {\n\t\t\tsqlAstArguments.get( 0 ).accept( translator );\n\t\t\tfor ( int i = 1; i < sqlAstArguments.size(); i++ ) {\n\t\t\t\tsqlAppender.append( ',' );\n\t\t\t\tsqlAstArguments.get( i ).accept( translator );\n\t\t\t}\n\t\t}\n\t\tsqlAppender.appendSql( ')' );\n\t\tif ( withinGroup != null && !withinGroup.isEmpty() ) {\n\t\t\ttranslator.getCurrentClauseStack().push( Clause.WITHIN_GROUP );\n\t\t\tsqlAppender.appendSql( \" within group (order by \" );\n\t\t\twithinGroup.get( 0 ).accept( translator );\n\t\t\tfor ( int i = 1; i < withinGroup.size(); i++ ) {\n\t\t\t\tsqlAppender.appendSql( ',' );\n\t\t\t\twithinGroup.get( i ).accept( translator );","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/dialect/function/InverseDistributionFunction.java#L81-L117","documentation":"InverseDistributionFunction is the shared renderer for inverse distribution aggregates (percentile_cont, percentile_disc, mode). When a FILTER clause is present and the target dialect's translator does not support FILTER, this renderer has no way to emulate the filter for an inverse distribution function and throws during SQL rendering.","triggerScenarios":"HQL: percentile_disc(0.5) within group (order by x) filter (where cond) or mode() within group (order by x) filter (where cond) on a dialect lacking FILTER support.","commonSituations":"Analytics HQL with filter clauses moved between databases; CI matrix runs against MySQL-family dialects; dialect upgrades that changed FILTER emulation availability.","solutions":["Move the filter predicate into the WHERE clause of a feeding subquery","Drop FILTER when it can be folded into the main query's WHERE clause","Use native SQL or a FILTER-capable dialect (e.g. PostgreSQL) for that query"],"exampleFix":"// before\nselect mode() within group (order by e.status) filter (where e.tenant = 1) from Event e\n\n// after\nselect mode() within group (order by t.status) from (select e.status from Event e where e.tenant = 1) t","handlingStrategy":"fallback","validationCode":"boolean filterSupported(SessionFactory sf) {\n    String dialect = sf.getJdbcServices().getDialect().getClass().getSimpleName();\n    return dialect.contains(\"PostgreSQL\") || dialect.contains(\"H2\"); // extend per your verified matrix\n}","typeGuard":null,"tryCatchPattern":"try {\n    return em.createQuery(hqlWithFilter, Object.class).getResultList();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"emulate filter clause\")) {\n        return em.createQuery(hqlWithWhere, Object.class).getResultList();\n    }\n    throw e;\n}","preventionTips":["Fold filter predicates into subquery WHERE clauses for portable HQL","Avoid FILTER on inverse distribution functions outside FILTER-capable dialects","Keep dialect capability checks near the query builders that need them"],"tags":["hibernate","hql","filter-clause","inverse-distribution","dialect-limitation"],"backgroundTag":"aggregate-filter-clause-unsupported","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}